* [dpdk-dev] [PATCH] cryptodev: decouple from PCI device
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:27 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCH] mbuf: use pktmbuf helper to create the pool Hemant Agrawal
` (34 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
This makes struct rte_cryptodev independent of struct rte_pci_device by
replacing it with a pointer to the generic struct rte_device.
This is inline with the recent changes in ethdev
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/crypto/qat/qat_qp.c | 12 +++++++++---
drivers/crypto/qat/rte_qat_cryptodev.c | 6 +++---
lib/librte_cryptodev/rte_cryptodev.c | 6 +++---
lib/librte_cryptodev/rte_cryptodev.h | 4 ++--
4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 2e7188b..07e63fc 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -135,6 +135,7 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
int socket_id)
{
struct qat_qp *qp;
+ struct rte_pci_device *pci_dev;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -153,7 +154,9 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
return -EINVAL;
}
- if (dev->pci_dev->mem_resource[0].addr == NULL) {
+ pci_dev = RTE_DEV_TO_PCI(dev->device);
+
+ if (pci_dev->mem_resource[0].addr == NULL) {
PMD_DRV_LOG(ERR, "Could not find VF config space "
"(UIO driver attached?).");
return -EINVAL;
@@ -174,7 +177,7 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
PMD_DRV_LOG(ERR, "Failed to alloc mem for qp struct");
return -ENOMEM;
}
- qp->mmap_bar_addr = dev->pci_dev->mem_resource[0].addr;
+ qp->mmap_bar_addr = pci_dev->mem_resource[0].addr;
rte_atomic16_init(&qp->inflights16);
if (qat_tx_queue_create(dev, &(qp->tx_q),
@@ -289,6 +292,7 @@ static void qat_queue_delete(struct qat_queue *queue)
void *io_addr;
const struct rte_memzone *qp_mz;
uint32_t queue_size_bytes = nb_desc*desc_size;
+ struct rte_pci_device *pci_dev;
PMD_INIT_FUNC_TRACE();
if (desc_size > ADF_MSG_SIZE_TO_BYTES(ADF_MAX_MSG_SIZE)) {
@@ -349,7 +353,9 @@ static void qat_queue_delete(struct qat_queue *queue)
queue_base = BUILD_RING_BASE_ADDR(queue->base_phys_addr,
queue->queue_size);
- io_addr = dev->pci_dev->mem_resource[0].addr;
+ pci_dev = RTE_DEV_TO_PCI(dev->device);
+
+ io_addr = pci_dev->mem_resource[0].addr;
WRITE_CSR_RING_BASE(io_addr, queue->hw_bundle_number,
queue->hw_queue_number, queue_base);
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 1e7ee61..840d828 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -88,9 +88,9 @@
PMD_INIT_FUNC_TRACE();
PMD_DRV_LOG(DEBUG, "Found crypto device at %02x:%02x.%x",
- cryptodev->pci_dev->addr.bus,
- cryptodev->pci_dev->addr.devid,
- cryptodev->pci_dev->addr.function);
+ RTE_DEV_TO_PCI(cryptodev->device)->addr.bus,
+ RTE_DEV_TO_PCI(cryptodev->device)->addr.devid,
+ RTE_DEV_TO_PCI(cryptodev->device)->addr.function);
cryptodev->dev_type = RTE_CRYPTODEV_QAT_SYM_PMD;
cryptodev->dev_ops = &crypto_qat_ops;
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..8402b6a 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -446,7 +446,7 @@ struct rte_cryptodev *
"device data");
}
- cryptodev->pci_dev = pci_dev;
+ cryptodev->device = &pci_dev->device;
cryptodev->driver = cryptodrv;
/* init user callbacks */
@@ -506,7 +506,7 @@ struct rte_cryptodev *
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
rte_free(cryptodev->data->dev_private);
- cryptodev->pci_dev = NULL;
+ cryptodev->device = NULL;
cryptodev->driver = NULL;
cryptodev->data = NULL;
@@ -867,7 +867,7 @@ struct rte_cryptodev *
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
- dev_info->pci_dev = dev->pci_dev;
+ dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
if (dev->driver)
dev_info->driver_name = dev->driver->pci_drv.driver.name;
}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8f63e8f..ef072d2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -621,8 +621,8 @@ struct rte_cryptodev {
/**< Functions exported by PMD */
uint64_t feature_flags;
/**< Supported features */
- struct rte_pci_device *pci_dev;
- /**< PCI info. supplied by probing */
+ struct rte_device *device;
+ /**< Backing device */
enum rte_cryptodev_type dev_type;
/**< Crypto device type */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] cryptodev: decouple from PCI device
2017-01-19 13:23 ` [dpdk-dev] [PATCH] cryptodev: decouple from PCI device Hemant Agrawal
@ 2017-01-19 13:27 ` Hemant Agrawal
2017-01-20 12:28 ` De Lara Guarch, Pablo
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:27 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, Shreyansh Jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Please ignore.
Apologies for repeated sent. This patch was posted earlier.
- Hemant
> -----Original Message-----
> From: Hemant Agrawal [mailto:hemant.agrawal@nxp.com]
> Sent: Thursday, January 19, 2017 6:53 PM
> To: dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com;
> ferruh.yigit@intel.com; jerin.jacob@caviumnetworks.com; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: [PATCH] cryptodev: decouple from PCI device
>
> This makes struct rte_cryptodev independent of struct rte_pci_device by
> replacing it with a pointer to the generic struct rte_device.
>
> This is inline with the recent changes in ethdev
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/crypto/qat/qat_qp.c | 12 +++++++++---
> drivers/crypto/qat/rte_qat_cryptodev.c | 6 +++---
> lib/librte_cryptodev/rte_cryptodev.c | 6 +++---
> lib/librte_cryptodev/rte_cryptodev.h | 4 ++--
> 4 files changed, 17 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c index
> 2e7188b..07e63fc 100644
> --- a/drivers/crypto/qat/qat_qp.c
> +++ b/drivers/crypto/qat/qat_qp.c
> @@ -135,6 +135,7 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
> int socket_id)
> {
> struct qat_qp *qp;
> + struct rte_pci_device *pci_dev;
> int ret;
>
> PMD_INIT_FUNC_TRACE();
> @@ -153,7 +154,9 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
> return -EINVAL;
> }
>
> - if (dev->pci_dev->mem_resource[0].addr == NULL) {
> + pci_dev = RTE_DEV_TO_PCI(dev->device);
> +
> + if (pci_dev->mem_resource[0].addr == NULL) {
> PMD_DRV_LOG(ERR, "Could not find VF config space "
> "(UIO driver attached?).");
> return -EINVAL;
> @@ -174,7 +177,7 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
> PMD_DRV_LOG(ERR, "Failed to alloc mem for qp struct");
> return -ENOMEM;
> }
> - qp->mmap_bar_addr = dev->pci_dev->mem_resource[0].addr;
> + qp->mmap_bar_addr = pci_dev->mem_resource[0].addr;
> rte_atomic16_init(&qp->inflights16);
>
> if (qat_tx_queue_create(dev, &(qp->tx_q), @@ -289,6 +292,7 @@
> static void qat_queue_delete(struct qat_queue *queue)
> void *io_addr;
> const struct rte_memzone *qp_mz;
> uint32_t queue_size_bytes = nb_desc*desc_size;
> + struct rte_pci_device *pci_dev;
>
> PMD_INIT_FUNC_TRACE();
> if (desc_size > ADF_MSG_SIZE_TO_BYTES(ADF_MAX_MSG_SIZE)) { @@ -
> 349,7 +353,9 @@ static void qat_queue_delete(struct qat_queue *queue)
>
> queue_base = BUILD_RING_BASE_ADDR(queue->base_phys_addr,
> queue->queue_size);
> - io_addr = dev->pci_dev->mem_resource[0].addr;
> + pci_dev = RTE_DEV_TO_PCI(dev->device);
> +
> + io_addr = pci_dev->mem_resource[0].addr;
>
> WRITE_CSR_RING_BASE(io_addr, queue->hw_bundle_number,
> queue->hw_queue_number, queue_base); diff --git
> a/drivers/crypto/qat/rte_qat_cryptodev.c
> b/drivers/crypto/qat/rte_qat_cryptodev.c
> index 1e7ee61..840d828 100644
> --- a/drivers/crypto/qat/rte_qat_cryptodev.c
> +++ b/drivers/crypto/qat/rte_qat_cryptodev.c
> @@ -88,9 +88,9 @@
>
> PMD_INIT_FUNC_TRACE();
> PMD_DRV_LOG(DEBUG, "Found crypto device at %02x:%02x.%x",
> - cryptodev->pci_dev->addr.bus,
> - cryptodev->pci_dev->addr.devid,
> - cryptodev->pci_dev->addr.function);
> + RTE_DEV_TO_PCI(cryptodev->device)->addr.bus,
> + RTE_DEV_TO_PCI(cryptodev->device)->addr.devid,
> + RTE_DEV_TO_PCI(cryptodev->device)->addr.function);
>
> cryptodev->dev_type = RTE_CRYPTODEV_QAT_SYM_PMD;
> cryptodev->dev_ops = &crypto_qat_ops;
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> b/lib/librte_cryptodev/rte_cryptodev.c
> index 127e8d0..8402b6a 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -446,7 +446,7 @@ struct rte_cryptodev *
> "device data");
> }
>
> - cryptodev->pci_dev = pci_dev;
> + cryptodev->device = &pci_dev->device;
> cryptodev->driver = cryptodrv;
>
> /* init user callbacks */
> @@ -506,7 +506,7 @@ struct rte_cryptodev *
> if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> rte_free(cryptodev->data->dev_private);
>
> - cryptodev->pci_dev = NULL;
> + cryptodev->device = NULL;
> cryptodev->driver = NULL;
> cryptodev->data = NULL;
>
> @@ -867,7 +867,7 @@ struct rte_cryptodev *
> RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>
> - dev_info->pci_dev = dev->pci_dev;
> + dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
> if (dev->driver)
> dev_info->driver_name = dev->driver->pci_drv.driver.name; }
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> b/lib/librte_cryptodev/rte_cryptodev.h
> index 8f63e8f..ef072d2 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -621,8 +621,8 @@ struct rte_cryptodev {
> /**< Functions exported by PMD */
> uint64_t feature_flags;
> /**< Supported features */
> - struct rte_pci_device *pci_dev;
> - /**< PCI info. supplied by probing */
> + struct rte_device *device;
> + /**< Backing device */
>
> enum rte_cryptodev_type dev_type;
> /**< Crypto device type */
> --
> 1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] cryptodev: decouple from PCI device
2017-01-19 13:27 ` Hemant Agrawal
@ 2017-01-20 12:28 ` De Lara Guarch, Pablo
0 siblings, 0 replies; 549+ messages in thread
From: De Lara Guarch, Pablo @ 2017-01-20 12:28 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, Richardson, Bruce, Shreyansh Jain, Mcnamara,
John, Yigit, Ferruh, jerin.jacob
Hi Hemant,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Hemant Agrawal
> Sent: Thursday, January 19, 2017 1:28 PM
> To: Hemant Agrawal; dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; Richardson, Bruce; Shreyansh Jain;
> Mcnamara, John; Yigit, Ferruh; jerin.jacob@caviumnetworks.com
> Subject: Re: [dpdk-dev] [PATCH] cryptodev: decouple from PCI device
>
> Please ignore.
>
> Apologies for repeated sent. This patch was posted earlier.
No worries. Next time, change the state of the patch to "Not Applicable" in Patchwork.
Thanks,
Pablo
>
> - Hemant
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH] mbuf: use pktmbuf helper to create the pool
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCH] cryptodev: decouple from PCI device Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:27 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 01/33] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
` (33 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Olivier Matz, Hemant Agrawal
When possible, replace the uses of rte_mempool_create() with
the helper provided in librte_mbuf: rte_pktmbuf_pool_create().
This is the preferred way to create a mbuf pool.
This also updates the documentation.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
This patch is derived from the RFC from Olivier:
http://dpdk.org/dev/patchwork/patch/15925/
| 11 ++++----
doc/guides/sample_app_ug/ip_reassembly.rst | 13 +++++----
doc/guides/sample_app_ug/ipv4_multicast.rst | 12 ++++----
doc/guides/sample_app_ug/l2_forward_job_stats.rst | 33 ++++++++--------------
.../sample_app_ug/l2_forward_real_virtual.rst | 26 +++++++----------
doc/guides/sample_app_ug/ptpclient.rst | 11 ++------
doc/guides/sample_app_ug/quota_watermark.rst | 26 ++++++-----------
drivers/net/bonding/rte_eth_bond_8023ad.c | 13 ++++-----
examples/ip_pipeline/init.c | 18 ++++++------
examples/ip_reassembly/main.c | 16 +++++------
examples/multi_process/l2fwd_fork/main.c | 13 +++------
examples/tep_termination/main.c | 16 +++++------
lib/librte_mbuf/rte_mbuf.c | 7 +++--
lib/librte_mbuf/rte_mbuf.h | 29 +++++++++++--------
14 files changed, 106 insertions(+), 138 deletions(-)
--git a/app/test/test_link_bonding_rssconf.c b/app/test/test_link_bonding_rssconf.c
index 34f1c16..9034f62 100644
--- a/app/test/test_link_bonding_rssconf.c
+++ b/app/test/test_link_bonding_rssconf.c
@@ -67,7 +67,7 @@
#define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d")
#define NUM_MBUFS 8191
-#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32
@@ -536,13 +536,12 @@ struct link_bonding_rssconf_unittest_params {
if (test_params.mbuf_pool == NULL) {
- test_params.mbuf_pool = rte_mempool_create("RSS_MBUF_POOL", NUM_MBUFS *
- SLAVE_COUNT, MBUF_SIZE, MBUF_CACHE_SIZE,
- sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
- NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+ test_params.mbuf_pool = rte_pktmbuf_pool_create(
+ "RSS_MBUF_POOL", NUM_MBUFS * SLAVE_COUNT,
+ MBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id());
TEST_ASSERT(test_params.mbuf_pool != NULL,
- "rte_mempool_create failed\n");
+ "rte_pktmbuf_pool_create failed\n");
}
/* Create / initialize ring eth devs. */
diff --git a/doc/guides/sample_app_ug/ip_reassembly.rst b/doc/guides/sample_app_ug/ip_reassembly.rst
index 3c5cc70..d5097c6 100644
--- a/doc/guides/sample_app_ug/ip_reassembly.rst
+++ b/doc/guides/sample_app_ug/ip_reassembly.rst
@@ -223,11 +223,14 @@ each RX queue uses its own mempool.
snprintf(buf, sizeof(buf), "mbuf_pool_%u_%u", lcore, queue);
- if ((rxq->pool = rte_mempool_create(buf, nb_mbuf, MBUF_SIZE, 0, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL, socket, MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET)) == NULL) {
-
- RTE_LOG(ERR, IP_RSMBL, "mempool_create(%s) failed", buf);
- return -1;
+ rxq->pool = rte_pktmbuf_pool_create(buf, nb_mbuf,
+ 0, /* cache size */
+ 0, /* priv size */
+ MBUF_DATA_SIZE, socket);
+ if (rxq->pool == NULL) {
+ RTE_LOG(ERR, IP_RSMBL,
+ "rte_pktmbuf_pool_create(%s) failed", buf);
+ return -1;
}
Packet Reassembly and Forwarding
diff --git a/doc/guides/sample_app_ug/ipv4_multicast.rst b/doc/guides/sample_app_ug/ipv4_multicast.rst
index 72da8c4..d9ff249 100644
--- a/doc/guides/sample_app_ug/ipv4_multicast.rst
+++ b/doc/guides/sample_app_ug/ipv4_multicast.rst
@@ -145,12 +145,12 @@ Memory pools for indirect buffers are initialized differently from the memory po
.. code-block:: c
- packet_pool = rte_mempool_create("packet_pool", NB_PKT_MBUF, PKT_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
-
- header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF, HDR_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
- clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
- CLONE_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+ packet_pool = rte_pktmbuf_pool_create("packet_pool", NB_PKT_MBUF, 32,
+ 0, PKT_MBUF_DATA_SIZE, rte_socket_id());
+ header_pool = rte_pktmbuf_pool_create("header_pool", NB_HDR_MBUF, 32,
+ 0, HDR_MBUF_DATA_SIZE, rte_socket_id());
+ clone_pool = rte_pktmbuf_pool_create("clone_pool", NB_CLONE_MBUF, 32,
+ 0, 0, rte_socket_id());
The reason for this is because indirect buffers are not supposed to hold any packet data and
therefore can be initialized with lower amount of reserved memory for each buffer.
diff --git a/doc/guides/sample_app_ug/l2_forward_job_stats.rst b/doc/guides/sample_app_ug/l2_forward_job_stats.rst
index 2444e36..a606b86 100644
--- a/doc/guides/sample_app_ug/l2_forward_job_stats.rst
+++ b/doc/guides/sample_app_ug/l2_forward_job_stats.rst
@@ -193,36 +193,25 @@ and the application to store network packet data:
.. code-block:: c
/* create the mbuf pool */
- l2fwd_pktmbuf_pool =
- rte_mempool_create("mbuf_pool", NB_MBUF,
- MBUF_SIZE, 32,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(), 0);
+ l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+ MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
+ rte_socket_id());
if (l2fwd_pktmbuf_pool == NULL)
rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
The rte_mempool is a generic structure used to handle pools of objects.
-In this case, it is necessary to create a pool that will be used by the driver,
-which expects to have some reserved space in the mempool structure,
-sizeof(struct rte_pktmbuf_pool_private) bytes.
-The number of allocated pkt mbufs is NB_MBUF, with a size of MBUF_SIZE each.
-A per-lcore cache of 32 mbufs is kept.
+In this case, it is necessary to create a pool that will be used by the driver.
+The number of allocated pkt mbufs is NB_MBUF, with a data room size of
+RTE_MBUF_DEFAULT_BUF_SIZE each.
+A per-lcore cache of MEMPOOL_CACHE_SIZE mbufs is kept.
The memory is allocated in rte_socket_id() socket,
but it is possible to extend this code to allocate one mbuf pool per socket.
-Two callback pointers are also given to the rte_mempool_create() function:
-
-* The first callback pointer is to rte_pktmbuf_pool_init() and is used
- to initialize the private data of the mempool, which is needed by the driver.
- This function is provided by the mbuf API, but can be copied and extended by the developer.
-
-* The second callback pointer given to rte_mempool_create() is the mbuf initializer.
- The default is used, that is, rte_pktmbuf_init(), which is provided in the rte_mbuf library.
- If a more complex application wants to extend the rte_pktmbuf structure for its own needs,
- a new function derived from rte_pktmbuf_init( ) can be created.
+The rte_pktmbuf_pool_create() function uses the default mbuf pool and mbuf
+initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
+An advanced application may want to use the mempool API to create the
+mbuf pool with more control.
Driver Initialization
~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
index cf15d1c..de86ac8 100644
--- a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
+++ b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
@@ -207,31 +207,25 @@ and the application to store network packet data:
/* create the mbuf pool */
- l2fwd_pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, SOCKET0, 0);
+ l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+ MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
+ rte_socket_id());
if (l2fwd_pktmbuf_pool == NULL)
rte_panic("Cannot init mbuf pool\n");
The rte_mempool is a generic structure used to handle pools of objects.
-In this case, it is necessary to create a pool that will be used by the driver,
-which expects to have some reserved space in the mempool structure,
-sizeof(struct rte_pktmbuf_pool_private) bytes.
-The number of allocated pkt mbufs is NB_MBUF, with a size of MBUF_SIZE each.
+In this case, it is necessary to create a pool that will be used by the driver.
+The number of allocated pkt mbufs is NB_MBUF, with a data room size of
+RTE_MBUF_DEFAULT_BUF_SIZE each.
A per-lcore cache of 32 mbufs is kept.
The memory is allocated in NUMA socket 0,
but it is possible to extend this code to allocate one mbuf pool per socket.
-Two callback pointers are also given to the rte_mempool_create() function:
-
-* The first callback pointer is to rte_pktmbuf_pool_init() and is used
- to initialize the private data of the mempool, which is needed by the driver.
- This function is provided by the mbuf API, but can be copied and extended by the developer.
-
-* The second callback pointer given to rte_mempool_create() is the mbuf initializer.
- The default is used, that is, rte_pktmbuf_init(), which is provided in the rte_mbuf library.
- If a more complex application wants to extend the rte_pktmbuf structure for its own needs,
- a new function derived from rte_pktmbuf_init( ) can be created.
+The rte_pktmbuf_pool_create() function uses the default mbuf pool and mbuf
+initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
+An advanced application may want to use the mempool API to create the
+mbuf pool with more control.
.. _l2_fwd_app_dvr_init:
diff --git a/doc/guides/sample_app_ug/ptpclient.rst b/doc/guides/sample_app_ug/ptpclient.rst
index 6e425b7..405a267 100644
--- a/doc/guides/sample_app_ug/ptpclient.rst
+++ b/doc/guides/sample_app_ug/ptpclient.rst
@@ -171,15 +171,8 @@ used by the application:
.. code-block:: c
- mbuf_pool = rte_mempool_create("MBUF_POOL",
- NUM_MBUFS * nb_ports,
- MBUF_SIZE,
- MBUF_CACHE_SIZE,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(),
- 0);
+ mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+ MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
Mbufs are the packet buffer structure used by DPDK. They are explained in
detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*.
diff --git a/doc/guides/sample_app_ug/quota_watermark.rst b/doc/guides/sample_app_ug/quota_watermark.rst
index c56683a..a0da8fe 100644
--- a/doc/guides/sample_app_ug/quota_watermark.rst
+++ b/doc/guides/sample_app_ug/quota_watermark.rst
@@ -254,32 +254,24 @@ It contains a set of mbuf objects that are used by the driver and the applicatio
.. code-block:: c
/* Create a pool of mbuf to store packets */
-
- mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL, MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
+ mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0,
+ MBUF_DATA_SIZE, rte_socket_id());
if (mbuf_pool == NULL)
rte_panic("%s\n", rte_strerror(rte_errno));
The rte_mempool is a generic structure used to handle pools of objects.
-In this case, it is necessary to create a pool that will be used by the driver,
-which expects to have some reserved space in the mempool structure, sizeof(struct rte_pktmbuf_pool_private) bytes.
+In this case, it is necessary to create a pool that will be used by the driver.
-The number of allocated pkt mbufs is MBUF_PER_POOL, with a size of MBUF_SIZE each.
+The number of allocated pkt mbufs is MBUF_PER_POOL, with a data room size
+of MBUF_DATA_SIZE each.
A per-lcore cache of 32 mbufs is kept.
The memory is allocated in on the master lcore's socket, but it is possible to extend this code to allocate one mbuf pool per socket.
-Two callback pointers are also given to the rte_mempool_create() function:
-
-* The first callback pointer is to rte_pktmbuf_pool_init() and is used to initialize the private data of the mempool,
- which is needed by the driver.
- This function is provided by the mbuf API, but can be copied and extended by the developer.
-
-* The second callback pointer given to rte_mempool_create() is the mbuf initializer.
-
-The default is used, that is, rte_pktmbuf_init(), which is provided in the rte_mbuf library.
-If a more complex application wants to extend the rte_pktmbuf structure for its own needs,
-a new function derived from rte_pktmbuf_init() can be created.
+The rte_pktmbuf_pool_create() function uses the default mbuf pool and mbuf
+initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
+An advanced application may want to use the mempool API to create the
+mbuf pool with more control.
Ports Configuration and Pairing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 2f7ae70..af211ca 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -888,8 +888,8 @@
RTE_ASSERT(port->tx_ring == NULL);
socket_id = rte_eth_devices[slave_id].data->numa_node;
- element_size = sizeof(struct slow_protocol_frame) + sizeof(struct rte_mbuf)
- + RTE_PKTMBUF_HEADROOM;
+ element_size = sizeof(struct slow_protocol_frame) +
+ RTE_PKTMBUF_HEADROOM;
/* The size of the mempool should be at least:
* the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
@@ -900,11 +900,10 @@
}
snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
- port->mbuf_pool = rte_mempool_create(mem_name,
- total_tx_desc, element_size,
- RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ? 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
- sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
- NULL, rte_pktmbuf_init, NULL, socket_id, MEMPOOL_F_NO_SPREAD);
+ port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
+ RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
+ 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
+ 0, element_size, socket_id);
/* Any memory allocation failure in initalization is critical because
* resources can't be free, so reinitialization is impossible. */
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 3b36b53..d55c3b4 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -324,16 +324,14 @@
struct app_mempool_params *p = &app->mempool_params[i];
APP_LOG(app, HIGH, "Initializing %s ...", p->name);
- app->mempool[i] = rte_mempool_create(
- p->name,
- p->pool_size,
- p->buffer_size,
- p->cache_size,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- p->cpu_socket_id,
- 0);
+ app->mempool[i] = rte_pktmbuf_pool_create(
+ p->name,
+ p->pool_size,
+ p->cache_size,
+ 0, /* priv_size */
+ p->buffer_size -
+ sizeof(struct rte_mbuf), /* mbuf data size */
+ p->cpu_socket_id);
if (app->mempool[i] == NULL)
rte_panic("%s init error\n", p->name);
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 50fe422..f6378bf 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -84,9 +84,7 @@
#define MAX_JUMBO_PKT_LEN 9600
-#define BUF_SIZE RTE_MBUF_DEFAULT_DATAROOM
-#define MBUF_SIZE \
- (BUF_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
#define NB_MBUF 8192
@@ -909,11 +907,13 @@ struct rte_lpm6_config lpm6_config = {
snprintf(buf, sizeof(buf), "mbuf_pool_%u_%u", lcore, queue);
- if ((rxq->pool = rte_mempool_create(buf, nb_mbuf, MBUF_SIZE, 0,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
- socket, MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET)) == NULL) {
- RTE_LOG(ERR, IP_RSMBL, "mempool_create(%s) failed", buf);
+ rxq->pool = rte_pktmbuf_pool_create(buf, nb_mbuf,
+ 0, /* cache size */
+ 0, /* priv size */
+ MBUF_DATA_SIZE, socket);
+ if (rxq->pool == NULL) {
+ RTE_LOG(ERR, IP_RSMBL,
+ "rte_pktmbuf_pool_create(%s) failed", buf);
return -1;
}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index 2d951d9..b34916e 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -77,8 +77,7 @@
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MBUF_NAME "mbuf_pool_%d"
-#define MBUF_SIZE \
-(RTE_MBUF_DEFAULT_DATAROOM + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
#define NB_MBUF 8192
#define RING_MASTER_NAME "l2fwd_ring_m2s_"
#define RING_SLAVE_NAME "l2fwd_ring_s2m_"
@@ -989,14 +988,10 @@ struct l2fwd_port_statistics {
flags = MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET;
snprintf(buf_name, RTE_MEMPOOL_NAMESIZE, MBUF_NAME, portid);
l2fwd_pktmbuf_pool[portid] =
- rte_mempool_create(buf_name, NB_MBUF,
- MBUF_SIZE, 32,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(), flags);
+ rte_pktmbuf_pool_create(buf_name, NB_MBUF, 32,
+ 0, MBUF_DATA_SIZE, rte_socket_id());
if (l2fwd_pktmbuf_pool[portid] == NULL)
- rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
+ rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
printf("Create mbuf %s\n", buf_name);
}
diff --git a/examples/tep_termination/main.c b/examples/tep_termination/main.c
index bd1dc96..20dafdb 100644
--- a/examples/tep_termination/main.c
+++ b/examples/tep_termination/main.c
@@ -68,7 +68,7 @@
(nb_switching_cores * MBUF_CACHE_SIZE))
#define MBUF_CACHE_SIZE 128
-#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
#define MAX_PKT_BURST 32 /* Max burst size for RX/TX */
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
@@ -1199,15 +1199,13 @@ static inline void __attribute__((always_inline))
MAX_SUP_PORTS);
}
/* Create the mbuf pool. */
- mbuf_pool = rte_mempool_create(
+ mbuf_pool = rte_pktmbuf_pool_create(
"MBUF_POOL",
- NUM_MBUFS_PER_PORT
- * valid_nb_ports,
- MBUF_SIZE, MBUF_CACHE_SIZE,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- rte_socket_id(), 0);
+ NUM_MBUFS_PER_PORT * valid_nb_ports,
+ MBUF_CACHE_SIZE,
+ 0,
+ MBUF_DATA_SIZE,
+ rte_socket_id());
if (mbuf_pool == NULL)
rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 72ad91e..3fb2700 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -62,7 +62,7 @@
/*
* ctrlmbuf constructor, given as a callback function to
- * rte_mempool_create()
+ * rte_mempool_obj_iter() or rte_mempool_create()
*/
void
rte_ctrlmbuf_init(struct rte_mempool *mp,
@@ -77,7 +77,8 @@
/*
* pktmbuf pool constructor, given as a callback function to
- * rte_mempool_create()
+ * rte_mempool_create(), or called directly if using
+ * rte_mempool_create_empty()/rte_mempool_populate()
*/
void
rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
@@ -110,7 +111,7 @@
/*
* pktmbuf constructor, given as a callback function to
- * rte_mempool_create().
+ * rte_mempool_obj_iter() or rte_mempool_create().
* Set the fields of a packet mbuf to their default values.
*/
void
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index bfce9f4..b1d4ccb 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -44,6 +44,13 @@
* buffers. The message buffers are stored in a mempool, using the
* RTE mempool library.
*
+ * The preferred way to create a mbuf pool is to use
+ * rte_pktmbuf_pool_create(). However, in some situations, an
+ * application may want to have more control (ex: populate the pool with
+ * specific memory), in this case it is possible to use functions from
+ * rte_mempool. See how rte_pktmbuf_pool_create() is implemented for
+ * details.
+ *
* This library provides an API to allocate/free packet mbufs, which are
* used to carry network packets.
*
@@ -810,14 +817,14 @@ static inline void __attribute__((always_inline))
* This function initializes some fields in an mbuf structure that are
* not modified by the user once created (mbuf type, origin pool, buffer
* start address, and so on). This function is given as a callback function
- * to rte_mempool_create() at pool creation time.
+ * to rte_mempool_obj_iter() or rte_mempool_create() at pool creation time.
*
* @param mp
* The mempool from which the mbuf is allocated.
* @param opaque_arg
* A pointer that can be used by the user to retrieve useful information
- * for mbuf initialization. This pointer comes from the ``init_arg``
- * parameter of rte_mempool_create().
+ * for mbuf initialization. This pointer is the opaque argument passed to
+ * rte_mempool_obj_iter() or rte_mempool_create().
* @param m
* The mbuf to initialize.
* @param i
@@ -891,14 +898,14 @@ void rte_ctrlmbuf_init(struct rte_mempool *mp, void *opaque_arg,
* This function initializes some fields in the mbuf structure that are
* not modified by the user once created (origin pool, buffer start
* address, and so on). This function is given as a callback function to
- * rte_mempool_create() at pool creation time.
+ * rte_mempool_obj_iter() or rte_mempool_create() at pool creation time.
*
* @param mp
* The mempool from which mbufs originate.
* @param opaque_arg
* A pointer that can be used by the user to retrieve useful information
- * for mbuf initialization. This pointer comes from the ``init_arg``
- * parameter of rte_mempool_create().
+ * for mbuf initialization. This pointer is the opaque argument passed to
+ * rte_mempool_obj_iter() or rte_mempool_create().
* @param m
* The mbuf to initialize.
* @param i
@@ -913,7 +920,8 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
*
* This function initializes the mempool private data in the case of a
* pktmbuf pool. This private data is needed by the driver. The
- * function is given as a callback function to rte_mempool_create() at
+ * function must be called on the mempool before it is used, or it
+ * can be given as a callback function to rte_mempool_create() at
* pool creation. It can be extended by the user, for example, to
* provide another packet size.
*
@@ -921,8 +929,8 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
* The mempool from which mbufs originate.
* @param opaque_arg
* A pointer that can be used by the user to retrieve useful information
- * for mbuf initialization. This pointer comes from the ``init_arg``
- * parameter of rte_mempool_create().
+ * for mbuf initialization. This pointer is the opaque argument passed to
+ * rte_mempool_create().
*/
void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
@@ -930,8 +938,7 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
* Create a mbuf pool.
*
* This function creates and initializes a packet mbuf pool. It is
- * a wrapper to rte_mempool_create() with the proper packet constructor
- * and mempool constructor.
+ * a wrapper to rte_mempool functions.
*
* @param name
* The name of the mbuf pool.
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] mbuf: use pktmbuf helper to create the pool
2017-01-19 13:23 ` [dpdk-dev] [PATCH] mbuf: use pktmbuf helper to create the pool Hemant Agrawal
@ 2017-01-19 13:27 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:27 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, Shreyansh Jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Olivier Matz
Please ignore.
Apologies for repeated sent. This patch was posted earlier.
- Hemant
> -----Original Message-----
> From: Hemant Agrawal [mailto:hemant.agrawal@nxp.com]
> Sent: Thursday, January 19, 2017 6:53 PM
> To: dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com;
> ferruh.yigit@intel.com; jerin.jacob@caviumnetworks.com; Olivier Matz
> <olivier.matz@6wind.com>; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: [PATCH] mbuf: use pktmbuf helper to create the pool
>
> When possible, replace the uses of rte_mempool_create() with the helper
> provided in librte_mbuf: rte_pktmbuf_pool_create().
>
> This is the preferred way to create a mbuf pool.
>
> This also updates the documentation.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> This patch is derived from the RFC from Olivier:
> http://dpdk.org/dev/patchwork/patch/15925/
>
> app/test/test_link_bonding_rssconf.c | 11 ++++----
> doc/guides/sample_app_ug/ip_reassembly.rst | 13 +++++----
> doc/guides/sample_app_ug/ipv4_multicast.rst | 12 ++++----
> doc/guides/sample_app_ug/l2_forward_job_stats.rst | 33 ++++++++-------------
> -
> .../sample_app_ug/l2_forward_real_virtual.rst | 26 +++++++----------
> doc/guides/sample_app_ug/ptpclient.rst | 11 ++------
> doc/guides/sample_app_ug/quota_watermark.rst | 26 ++++++-----------
> drivers/net/bonding/rte_eth_bond_8023ad.c | 13 ++++-----
> examples/ip_pipeline/init.c | 18 ++++++------
> examples/ip_reassembly/main.c | 16 +++++------
> examples/multi_process/l2fwd_fork/main.c | 13 +++------
> examples/tep_termination/main.c | 16 +++++------
> lib/librte_mbuf/rte_mbuf.c | 7 +++--
> lib/librte_mbuf/rte_mbuf.h | 29 +++++++++++--------
> 14 files changed, 106 insertions(+), 138 deletions(-)
>
> diff --git a/app/test/test_link_bonding_rssconf.c
> b/app/test/test_link_bonding_rssconf.c
> index 34f1c16..9034f62 100644
> --- a/app/test/test_link_bonding_rssconf.c
> +++ b/app/test/test_link_bonding_rssconf.c
> @@ -67,7 +67,7 @@
> #define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d")
>
> #define NUM_MBUFS 8191
> -#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) +
> RTE_PKTMBUF_HEADROOM)
> +#define MBUF_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
> #define MBUF_CACHE_SIZE 250
> #define BURST_SIZE 32
>
> @@ -536,13 +536,12 @@ struct link_bonding_rssconf_unittest_params {
>
> if (test_params.mbuf_pool == NULL) {
>
> - test_params.mbuf_pool =
> rte_mempool_create("RSS_MBUF_POOL", NUM_MBUFS *
> - SLAVE_COUNT, MBUF_SIZE,
> MBUF_CACHE_SIZE,
> - sizeof(struct rte_pktmbuf_pool_private),
> rte_pktmbuf_pool_init,
> - NULL, rte_pktmbuf_init, NULL, rte_socket_id(),
> 0);
> + test_params.mbuf_pool = rte_pktmbuf_pool_create(
> + "RSS_MBUF_POOL", NUM_MBUFS * SLAVE_COUNT,
> + MBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id());
>
> TEST_ASSERT(test_params.mbuf_pool != NULL,
> - "rte_mempool_create failed\n");
> + "rte_pktmbuf_pool_create failed\n");
> }
>
> /* Create / initialize ring eth devs. */ diff --git
> a/doc/guides/sample_app_ug/ip_reassembly.rst
> b/doc/guides/sample_app_ug/ip_reassembly.rst
> index 3c5cc70..d5097c6 100644
> --- a/doc/guides/sample_app_ug/ip_reassembly.rst
> +++ b/doc/guides/sample_app_ug/ip_reassembly.rst
> @@ -223,11 +223,14 @@ each RX queue uses its own mempool.
>
> snprintf(buf, sizeof(buf), "mbuf_pool_%u_%u", lcore, queue);
>
> - if ((rxq->pool = rte_mempool_create(buf, nb_mbuf, MBUF_SIZE, 0,
> sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL, socket, MEMPOOL_F_SP_PUT |
> MEMPOOL_F_SC_GET)) == NULL) {
> -
> - RTE_LOG(ERR, IP_RSMBL, "mempool_create(%s) failed", buf);
> - return -1;
> + rxq->pool = rte_pktmbuf_pool_create(buf, nb_mbuf,
> + 0, /* cache size */
> + 0, /* priv size */
> + MBUF_DATA_SIZE, socket);
> + if (rxq->pool == NULL) {
> + RTE_LOG(ERR, IP_RSMBL,
> + "rte_pktmbuf_pool_create(%s) failed", buf);
> + return -1;
> }
>
> Packet Reassembly and Forwarding
> diff --git a/doc/guides/sample_app_ug/ipv4_multicast.rst
> b/doc/guides/sample_app_ug/ipv4_multicast.rst
> index 72da8c4..d9ff249 100644
> --- a/doc/guides/sample_app_ug/ipv4_multicast.rst
> +++ b/doc/guides/sample_app_ug/ipv4_multicast.rst
> @@ -145,12 +145,12 @@ Memory pools for indirect buffers are initialized
> differently from the memory po
>
> .. code-block:: c
>
> - packet_pool = rte_mempool_create("packet_pool", NB_PKT_MBUF,
> PKT_MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
> rte_socket_id(), 0);
> -
> - header_pool = rte_mempool_create("header_pool", NB_HDR_MBUF,
> HDR_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL, rte_socket_id(),
> 0);
> - clone_pool = rte_mempool_create("clone_pool", NB_CLONE_MBUF,
> - CLONE_MBUF_SIZE, 32, 0, NULL, NULL, rte_pktmbuf_init, NULL,
> rte_socket_id(), 0);
> + packet_pool = rte_pktmbuf_pool_create("packet_pool", NB_PKT_MBUF, 32,
> + 0, PKT_MBUF_DATA_SIZE, rte_socket_id());
> + header_pool = rte_pktmbuf_pool_create("header_pool", NB_HDR_MBUF,
> 32,
> + 0, HDR_MBUF_DATA_SIZE, rte_socket_id());
> + clone_pool = rte_pktmbuf_pool_create("clone_pool", NB_CLONE_MBUF,
> 32,
> + 0, 0, rte_socket_id());
>
> The reason for this is because indirect buffers are not supposed to hold any
> packet data and therefore can be initialized with lower amount of reserved
> memory for each buffer.
> diff --git a/doc/guides/sample_app_ug/l2_forward_job_stats.rst
> b/doc/guides/sample_app_ug/l2_forward_job_stats.rst
> index 2444e36..a606b86 100644
> --- a/doc/guides/sample_app_ug/l2_forward_job_stats.rst
> +++ b/doc/guides/sample_app_ug/l2_forward_job_stats.rst
> @@ -193,36 +193,25 @@ and the application to store network packet data:
> .. code-block:: c
>
> /* create the mbuf pool */
> - l2fwd_pktmbuf_pool =
> - rte_mempool_create("mbuf_pool", NB_MBUF,
> - MBUF_SIZE, 32,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - rte_socket_id(), 0);
> + l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
> + MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
> + rte_socket_id());
>
> if (l2fwd_pktmbuf_pool == NULL)
> rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
>
> The rte_mempool is a generic structure used to handle pools of objects.
> -In this case, it is necessary to create a pool that will be used by the driver, -
> which expects to have some reserved space in the mempool structure, -
> sizeof(struct rte_pktmbuf_pool_private) bytes.
> -The number of allocated pkt mbufs is NB_MBUF, with a size of MBUF_SIZE
> each.
> -A per-lcore cache of 32 mbufs is kept.
> +In this case, it is necessary to create a pool that will be used by the driver.
> +The number of allocated pkt mbufs is NB_MBUF, with a data room size of
> +RTE_MBUF_DEFAULT_BUF_SIZE each.
> +A per-lcore cache of MEMPOOL_CACHE_SIZE mbufs is kept.
> The memory is allocated in rte_socket_id() socket, but it is possible to extend
> this code to allocate one mbuf pool per socket.
>
> -Two callback pointers are also given to the rte_mempool_create() function:
> -
> -* The first callback pointer is to rte_pktmbuf_pool_init() and is used
> - to initialize the private data of the mempool, which is needed by the driver.
> - This function is provided by the mbuf API, but can be copied and extended by
> the developer.
> -
> -* The second callback pointer given to rte_mempool_create() is the mbuf
> initializer.
> - The default is used, that is, rte_pktmbuf_init(), which is provided in the
> rte_mbuf library.
> - If a more complex application wants to extend the rte_pktmbuf structure for
> its own needs,
> - a new function derived from rte_pktmbuf_init( ) can be created.
> +The rte_pktmbuf_pool_create() function uses the default mbuf pool and
> +mbuf initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
> +An advanced application may want to use the mempool API to create the
> +mbuf pool with more control.
>
> Driver Initialization
> ~~~~~~~~~~~~~~~~~~~~~
> diff --git a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
> b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
> index cf15d1c..de86ac8 100644
> --- a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
> +++ b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst
> @@ -207,31 +207,25 @@ and the application to store network packet data:
>
> /* create the mbuf pool */
>
> - l2fwd_pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF,
> MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, SOCKET0, 0);
> + l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
> + MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
> + rte_socket_id());
>
> if (l2fwd_pktmbuf_pool == NULL)
> rte_panic("Cannot init mbuf pool\n");
>
> The rte_mempool is a generic structure used to handle pools of objects.
> -In this case, it is necessary to create a pool that will be used by the driver, -
> which expects to have some reserved space in the mempool structure, -
> sizeof(struct rte_pktmbuf_pool_private) bytes.
> -The number of allocated pkt mbufs is NB_MBUF, with a size of MBUF_SIZE
> each.
> +In this case, it is necessary to create a pool that will be used by the driver.
> +The number of allocated pkt mbufs is NB_MBUF, with a data room size of
> +RTE_MBUF_DEFAULT_BUF_SIZE each.
> A per-lcore cache of 32 mbufs is kept.
> The memory is allocated in NUMA socket 0, but it is possible to extend this
> code to allocate one mbuf pool per socket.
>
> -Two callback pointers are also given to the rte_mempool_create() function:
> -
> -* The first callback pointer is to rte_pktmbuf_pool_init() and is used
> - to initialize the private data of the mempool, which is needed by the driver.
> - This function is provided by the mbuf API, but can be copied and extended by
> the developer.
> -
> -* The second callback pointer given to rte_mempool_create() is the mbuf
> initializer.
> - The default is used, that is, rte_pktmbuf_init(), which is provided in the
> rte_mbuf library.
> - If a more complex application wants to extend the rte_pktmbuf structure for
> its own needs,
> - a new function derived from rte_pktmbuf_init( ) can be created.
> +The rte_pktmbuf_pool_create() function uses the default mbuf pool and
> +mbuf initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
> +An advanced application may want to use the mempool API to create the
> +mbuf pool with more control.
>
> .. _l2_fwd_app_dvr_init:
>
> diff --git a/doc/guides/sample_app_ug/ptpclient.rst
> b/doc/guides/sample_app_ug/ptpclient.rst
> index 6e425b7..405a267 100644
> --- a/doc/guides/sample_app_ug/ptpclient.rst
> +++ b/doc/guides/sample_app_ug/ptpclient.rst
> @@ -171,15 +171,8 @@ used by the application:
>
> .. code-block:: c
>
> - mbuf_pool = rte_mempool_create("MBUF_POOL",
> - NUM_MBUFS * nb_ports,
> - MBUF_SIZE,
> - MBUF_CACHE_SIZE,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - rte_socket_id(),
> - 0);
> + mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS *
> nb_ports,
> + MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
> rte_socket_id());
>
> Mbufs are the packet buffer structure used by DPDK. They are explained in
> detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*.
> diff --git a/doc/guides/sample_app_ug/quota_watermark.rst
> b/doc/guides/sample_app_ug/quota_watermark.rst
> index c56683a..a0da8fe 100644
> --- a/doc/guides/sample_app_ug/quota_watermark.rst
> +++ b/doc/guides/sample_app_ug/quota_watermark.rst
> @@ -254,32 +254,24 @@ It contains a set of mbuf objects that are used by the
> driver and the applicatio .. code-block:: c
>
> /* Create a pool of mbuf to store packets */
> -
> - mbuf_pool = rte_mempool_create("mbuf_pool", MBUF_PER_POOL,
> MBUF_SIZE, 32, sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0);
> + mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32,
> 0,
> + MBUF_DATA_SIZE, rte_socket_id());
>
> if (mbuf_pool == NULL)
> rte_panic("%s\n", rte_strerror(rte_errno));
>
> The rte_mempool is a generic structure used to handle pools of objects.
> -In this case, it is necessary to create a pool that will be used by the driver, -
> which expects to have some reserved space in the mempool structure,
> sizeof(struct rte_pktmbuf_pool_private) bytes.
> +In this case, it is necessary to create a pool that will be used by the driver.
>
> -The number of allocated pkt mbufs is MBUF_PER_POOL, with a size of
> MBUF_SIZE each.
> +The number of allocated pkt mbufs is MBUF_PER_POOL, with a data room
> +size of MBUF_DATA_SIZE each.
> A per-lcore cache of 32 mbufs is kept.
> The memory is allocated in on the master lcore's socket, but it is possible to
> extend this code to allocate one mbuf pool per socket.
>
> -Two callback pointers are also given to the rte_mempool_create() function:
> -
> -* The first callback pointer is to rte_pktmbuf_pool_init() and is used to
> initialize the private data of the mempool,
> - which is needed by the driver.
> - This function is provided by the mbuf API, but can be copied and extended by
> the developer.
> -
> -* The second callback pointer given to rte_mempool_create() is the mbuf
> initializer.
> -
> -The default is used, that is, rte_pktmbuf_init(), which is provided in the
> rte_mbuf library.
> -If a more complex application wants to extend the rte_pktmbuf structure for its
> own needs, -a new function derived from rte_pktmbuf_init() can be created.
> +The rte_pktmbuf_pool_create() function uses the default mbuf pool and
> +mbuf initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init().
> +An advanced application may want to use the mempool API to create the
> +mbuf pool with more control.
>
> Ports Configuration and Pairing
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c
> b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index 2f7ae70..af211ca 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -888,8 +888,8 @@
> RTE_ASSERT(port->tx_ring == NULL);
> socket_id = rte_eth_devices[slave_id].data->numa_node;
>
> - element_size = sizeof(struct slow_protocol_frame) + sizeof(struct
> rte_mbuf)
> - + RTE_PKTMBUF_HEADROOM;
> + element_size = sizeof(struct slow_protocol_frame) +
> + RTE_PKTMBUF_HEADROOM;
>
> /* The size of the mempool should be at least:
> * the sum of the TX descriptors +
> BOND_MODE_8023AX_SLAVE_TX_PKTS */ @@ -900,11 +900,10 @@
> }
>
> snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool",
> slave_id);
> - port->mbuf_pool = rte_mempool_create(mem_name,
> - total_tx_desc, element_size,
> - RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ? 32 :
> RTE_MEMPOOL_CACHE_MAX_SIZE,
> - sizeof(struct rte_pktmbuf_pool_private),
> rte_pktmbuf_pool_init,
> - NULL, rte_pktmbuf_init, NULL, socket_id,
> MEMPOOL_F_NO_SPREAD);
> + port->mbuf_pool = rte_pktmbuf_pool_create(mem_name,
> total_tx_desc,
> + RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
> + 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
> + 0, element_size, socket_id);
>
> /* Any memory allocation failure in initalization is critical because
> * resources can't be free, so reinitialization is impossible. */ diff --git
> a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c index
> 3b36b53..d55c3b4 100644
> --- a/examples/ip_pipeline/init.c
> +++ b/examples/ip_pipeline/init.c
> @@ -324,16 +324,14 @@
> struct app_mempool_params *p = &app->mempool_params[i];
>
> APP_LOG(app, HIGH, "Initializing %s ...", p->name);
> - app->mempool[i] = rte_mempool_create(
> - p->name,
> - p->pool_size,
> - p->buffer_size,
> - p->cache_size,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - p->cpu_socket_id,
> - 0);
> + app->mempool[i] = rte_pktmbuf_pool_create(
> + p->name,
> + p->pool_size,
> + p->cache_size,
> + 0, /* priv_size */
> + p->buffer_size -
> + sizeof(struct rte_mbuf), /* mbuf data size */
> + p->cpu_socket_id);
>
> if (app->mempool[i] == NULL)
> rte_panic("%s init error\n", p->name); diff --git
> a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c index
> 50fe422..f6378bf 100644
> --- a/examples/ip_reassembly/main.c
> +++ b/examples/ip_reassembly/main.c
> @@ -84,9 +84,7 @@
>
> #define MAX_JUMBO_PKT_LEN 9600
>
> -#define BUF_SIZE RTE_MBUF_DEFAULT_DATAROOM
> -#define MBUF_SIZE \
> - (BUF_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
> +#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
>
> #define NB_MBUF 8192
>
> @@ -909,11 +907,13 @@ struct rte_lpm6_config lpm6_config = {
>
> snprintf(buf, sizeof(buf), "mbuf_pool_%u_%u", lcore, queue);
>
> - if ((rxq->pool = rte_mempool_create(buf, nb_mbuf, MBUF_SIZE, 0,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
> - socket, MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET))
> == NULL) {
> - RTE_LOG(ERR, IP_RSMBL, "mempool_create(%s) failed", buf);
> + rxq->pool = rte_pktmbuf_pool_create(buf, nb_mbuf,
> + 0, /* cache size */
> + 0, /* priv size */
> + MBUF_DATA_SIZE, socket);
> + if (rxq->pool == NULL) {
> + RTE_LOG(ERR, IP_RSMBL,
> + "rte_pktmbuf_pool_create(%s) failed", buf);
> return -1;
> }
>
> diff --git a/examples/multi_process/l2fwd_fork/main.c
> b/examples/multi_process/l2fwd_fork/main.c
> index 2d951d9..b34916e 100644
> --- a/examples/multi_process/l2fwd_fork/main.c
> +++ b/examples/multi_process/l2fwd_fork/main.c
> @@ -77,8 +77,7 @@
>
> #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
> #define MBUF_NAME "mbuf_pool_%d"
> -#define MBUF_SIZE \
> -(RTE_MBUF_DEFAULT_DATAROOM + sizeof(struct rte_mbuf) +
> RTE_PKTMBUF_HEADROOM)
> +#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
> #define NB_MBUF 8192
> #define RING_MASTER_NAME "l2fwd_ring_m2s_"
> #define RING_SLAVE_NAME "l2fwd_ring_s2m_"
> @@ -989,14 +988,10 @@ struct l2fwd_port_statistics {
> flags = MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET;
> snprintf(buf_name, RTE_MEMPOOL_NAMESIZE, MBUF_NAME,
> portid);
> l2fwd_pktmbuf_pool[portid] =
> - rte_mempool_create(buf_name, NB_MBUF,
> - MBUF_SIZE, 32,
> - sizeof(struct
> rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - rte_socket_id(), flags);
> + rte_pktmbuf_pool_create(buf_name, NB_MBUF, 32,
> + 0, MBUF_DATA_SIZE, rte_socket_id());
> if (l2fwd_pktmbuf_pool[portid] == NULL)
> - rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
> + rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
>
> printf("Create mbuf %s\n", buf_name);
> }
> diff --git a/examples/tep_termination/main.c
> b/examples/tep_termination/main.c index bd1dc96..20dafdb 100644
> --- a/examples/tep_termination/main.c
> +++ b/examples/tep_termination/main.c
> @@ -68,7 +68,7 @@
> (nb_switching_cores * MBUF_CACHE_SIZE))
>
> #define MBUF_CACHE_SIZE 128
> -#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) +
> RTE_PKTMBUF_HEADROOM)
> +#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
>
> #define MAX_PKT_BURST 32 /* Max burst size for RX/TX */
> #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
> @@ -1199,15 +1199,13 @@ static inline void __attribute__((always_inline))
> MAX_SUP_PORTS);
> }
> /* Create the mbuf pool. */
> - mbuf_pool = rte_mempool_create(
> + mbuf_pool = rte_pktmbuf_pool_create(
> "MBUF_POOL",
> - NUM_MBUFS_PER_PORT
> - * valid_nb_ports,
> - MBUF_SIZE, MBUF_CACHE_SIZE,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - rte_socket_id(), 0);
> + NUM_MBUFS_PER_PORT * valid_nb_ports,
> + MBUF_CACHE_SIZE,
> + 0,
> + MBUF_DATA_SIZE,
> + rte_socket_id());
> if (mbuf_pool == NULL)
> rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
>
> diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index
> 72ad91e..3fb2700 100644
> --- a/lib/librte_mbuf/rte_mbuf.c
> +++ b/lib/librte_mbuf/rte_mbuf.c
> @@ -62,7 +62,7 @@
>
> /*
> * ctrlmbuf constructor, given as a callback function to
> - * rte_mempool_create()
> + * rte_mempool_obj_iter() or rte_mempool_create()
> */
> void
> rte_ctrlmbuf_init(struct rte_mempool *mp, @@ -77,7 +77,8 @@
>
> /*
> * pktmbuf pool constructor, given as a callback function to
> - * rte_mempool_create()
> + * rte_mempool_create(), or called directly if using
> + * rte_mempool_create_empty()/rte_mempool_populate()
> */
> void
> rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg) @@ -
> 110,7 +111,7 @@
>
> /*
> * pktmbuf constructor, given as a callback function to
> - * rte_mempool_create().
> + * rte_mempool_obj_iter() or rte_mempool_create().
> * Set the fields of a packet mbuf to their default values.
> */
> void
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index
> bfce9f4..b1d4ccb 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -44,6 +44,13 @@
> * buffers. The message buffers are stored in a mempool, using the
> * RTE mempool library.
> *
> + * The preferred way to create a mbuf pool is to use
> + * rte_pktmbuf_pool_create(). However, in some situations, an
> + * application may want to have more control (ex: populate the pool
> + with
> + * specific memory), in this case it is possible to use functions from
> + * rte_mempool. See how rte_pktmbuf_pool_create() is implemented for
> + * details.
> + *
> * This library provides an API to allocate/free packet mbufs, which are
> * used to carry network packets.
> *
> @@ -810,14 +817,14 @@ static inline void __attribute__((always_inline))
> * This function initializes some fields in an mbuf structure that are
> * not modified by the user once created (mbuf type, origin pool, buffer
> * start address, and so on). This function is given as a callback function
> - * to rte_mempool_create() at pool creation time.
> + * to rte_mempool_obj_iter() or rte_mempool_create() at pool creation time.
> *
> * @param mp
> * The mempool from which the mbuf is allocated.
> * @param opaque_arg
> * A pointer that can be used by the user to retrieve useful information
> - * for mbuf initialization. This pointer comes from the ``init_arg``
> - * parameter of rte_mempool_create().
> + * for mbuf initialization. This pointer is the opaque argument passed to
> + * rte_mempool_obj_iter() or rte_mempool_create().
> * @param m
> * The mbuf to initialize.
> * @param i
> @@ -891,14 +898,14 @@ void rte_ctrlmbuf_init(struct rte_mempool *mp, void
> *opaque_arg,
> * This function initializes some fields in the mbuf structure that are
> * not modified by the user once created (origin pool, buffer start
> * address, and so on). This function is given as a callback function to
> - * rte_mempool_create() at pool creation time.
> + * rte_mempool_obj_iter() or rte_mempool_create() at pool creation time.
> *
> * @param mp
> * The mempool from which mbufs originate.
> * @param opaque_arg
> * A pointer that can be used by the user to retrieve useful information
> - * for mbuf initialization. This pointer comes from the ``init_arg``
> - * parameter of rte_mempool_create().
> + * for mbuf initialization. This pointer is the opaque argument passed to
> + * rte_mempool_obj_iter() or rte_mempool_create().
> * @param m
> * The mbuf to initialize.
> * @param i
> @@ -913,7 +920,8 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void
> *opaque_arg,
> *
> * This function initializes the mempool private data in the case of a
> * pktmbuf pool. This private data is needed by the driver. The
> - * function is given as a callback function to rte_mempool_create() at
> + * function must be called on the mempool before it is used, or it
> + * can be given as a callback function to rte_mempool_create() at
> * pool creation. It can be extended by the user, for example, to
> * provide another packet size.
> *
> @@ -921,8 +929,8 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void
> *opaque_arg,
> * The mempool from which mbufs originate.
> * @param opaque_arg
> * A pointer that can be used by the user to retrieve useful information
> - * for mbuf initialization. This pointer comes from the ``init_arg``
> - * parameter of rte_mempool_create().
> + * for mbuf initialization. This pointer is the opaque argument passed to
> + * rte_mempool_create().
> */
> void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
>
> @@ -930,8 +938,7 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void
> *opaque_arg,
> * Create a mbuf pool.
> *
> * This function creates and initializes a packet mbuf pool. It is
> - * a wrapper to rte_mempool_create() with the proper packet constructor
> - * and mempool constructor.
> + * a wrapper to rte_mempool functions.
> *
> * @param name
> * The name of the mbuf pool.
> --
> 1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 01/33] mk/dpaa2: add the crc support to the machine type
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCH] cryptodev: decouple from PCI device Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCH] mbuf: use pktmbuf helper to create the pool Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details Hemant Agrawal
` (32 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
mk/machine/dpaa2/rte.vars.mk | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mk/machine/dpaa2/rte.vars.mk b/mk/machine/dpaa2/rte.vars.mk
index 8541633..e4735c2 100644
--- a/mk/machine/dpaa2/rte.vars.mk
+++ b/mk/machine/dpaa2/rte.vars.mk
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -53,7 +54,7 @@
# CPU_CFLAGS =
# CPU_LDFLAGS =
# CPU_ASFLAGS =
-MACHINE_CFLAGS += -march=armv8-a
+MACHINE_CFLAGS += -march=armv8-a+crc
ifdef CONFIG_RTE_ARCH_ARM_TUNE
MACHINE_CFLAGS += -mcpu=$(CONFIG_RTE_ARCH_ARM_TUNE)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (2 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 01/33] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 17:08 ` Thomas Monjalon
2017-01-19 17:34 ` Mcnamara, John
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
` (31 subsequent siblings)
35 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 8 +
doc/guides/nics/dpaa2.rst | 594 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 8 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 11 +
5 files changed, 622 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index f071138..d79e1a5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -354,6 +354,14 @@ M: Alejandro Lucero <alejandro.lucero@netronome.com>
F: drivers/net/nfp/
F: doc/guides/nics/nfp.rst
+NXP DPAA2 PMD
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/bus/fslmc/
+F: drivers/common/dpaa2/
+F: drivers/net/dpaa2/
+F: drivers/pool/dpaa2/
+F: doc/guides/nics/dpaa2.rst
+
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..0b30a6f
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,594 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+This driver relies on external libraries and kernel drivers for resources
+allocations and initialization. The following dependencies are not part of
+DPDK and must be installed separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_fslmcbus`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_COMMON`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2_qbman``,
+ and ``librte_pmd_dpaa2_dpio`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b2ad6ec
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,8 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 87f9334..be21e8a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 0ecd720..4d80005 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -15,6 +15,17 @@ DPDK Release 17.02
firefox build/doc/html/guides/rel_notes/release_17_02.html
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
New Features
------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details Hemant Agrawal
@ 2017-01-19 17:08 ` Thomas Monjalon
2017-01-20 4:47 ` Hemant Agrawal
2017-01-19 17:34 ` Mcnamara, John
1 sibling, 1 reply; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-19 17:08 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
2017-01-19 18:53, Hemant Agrawal:
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> +NXP DPAA2 PMD
> +M: Hemant Agrawal <hemant.agrawal@nxp.com>
> +F: drivers/bus/fslmc/
> +F: drivers/common/dpaa2/
> +F: drivers/net/dpaa2/
> +F: drivers/pool/dpaa2/
> +F: doc/guides/nics/dpaa2.rst
Please introduce line by line in the patches
adding these files.
> +++ b/doc/guides/nics/features/dpaa2.ini
> @@ -0,0 +1,8 @@
> +;
> +; Supported features of the 'dpaa2' network poll mode driver.
> +;
> +; Refer to default.ini for the full list of available PMD features.
> +;
> +[Features]
> +ARMv8 = Y
> +Usage doc = Y
You should introduce this file with the first PMD patch.
> +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
> +
> + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on this new
> + driver.
> +
> +* **Added a new driver for NXP DPAA2 Network PMD.**
> +
> + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on this new
> + driver.
You can use sphinx references to create a link in the generated HTML.
Please move doc patch after (or within) the code.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details
2017-01-19 17:08 ` Thomas Monjalon
@ 2017-01-20 4:47 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 4:47 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
On 1/19/2017 10:38 PM, Thomas Monjalon wrote:
> 2017-01-19 18:53, Hemant Agrawal:
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> +NXP DPAA2 PMD
>> +M: Hemant Agrawal <hemant.agrawal@nxp.com>
>> +F: drivers/bus/fslmc/
>> +F: drivers/common/dpaa2/
>> +F: drivers/net/dpaa2/
>> +F: drivers/pool/dpaa2/
>> +F: doc/guides/nics/dpaa2.rst
>
> Please introduce line by line in the patches
> adding these files.
>
Ok
>> +++ b/doc/guides/nics/features/dpaa2.ini
>> @@ -0,0 +1,8 @@
>> +;
>> +; Supported features of the 'dpaa2' network poll mode driver.
>> +;
>> +; Refer to default.ini for the full list of available PMD features.
>> +;
>> +[Features]
>> +ARMv8 = Y
>> +Usage doc = Y
>
> You should introduce this file with the first PMD patch.
>
Ok
>> +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
>> +
>> + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
>> + "Network Interface Controller Drivers" document for more details on this new
>> + driver.
>> +
>> +* **Added a new driver for NXP DPAA2 Network PMD.**
>> +
>> + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
>> + "Network Interface Controller Drivers" document for more details on this new
>> + driver.
>
> You can use sphinx references to create a link in the generated HTML.
>
> Please move doc patch after (or within) the code.
>
>
ok
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details Hemant Agrawal
2017-01-19 17:08 ` Thomas Monjalon
@ 2017-01-19 17:34 ` Mcnamara, John
2017-01-20 4:46 ` Hemant Agrawal
1 sibling, 1 reply; 549+ messages in thread
From: Mcnamara, John @ 2017-01-19 17:34 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, Richardson, Bruce, shreyansh.jain, Yigit,
Ferruh, jerin.jacob
> -----Original Message-----
> From: Hemant Agrawal [mailto:hemant.agrawal@nxp.com]
> Sent: Thursday, January 19, 2017 1:23 PM
> To: dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; Richardson, Bruce
> <bruce.richardson@intel.com>; shreyansh.jain@nxp.com; Mcnamara, John
> <john.mcnamara@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> jerin.jacob@caviumnetworks.com; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: [PATCHv5 02/33] doc: add dpaa2 nic details
>
>...
>
> +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
> +
> + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on
> + this new driver.
> +
> +* **Added a new driver for NXP DPAA2 Network PMD.**
> +
> + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on
> + this new driver.
>
> New Features
> ------------
These additions should be after "New Features" and not before, if you do
another revision you can fix it. If not it could be fixed on commit or I
can fix it in the final Release note review.
But overall the NIC guide is very good.
Acked-by: John McNamara <john.mcnamara@intel.com>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details
2017-01-19 17:34 ` Mcnamara, John
@ 2017-01-20 4:46 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 4:46 UTC (permalink / raw)
To: Mcnamara, John, dev
Cc: thomas.monjalon, Richardson, Bruce, shreyansh.jain, Yigit,
Ferruh, jerin.jacob
On 1/19/2017 11:04 PM, Mcnamara, John wrote:
>
>
>> -----Original Message-----
>> From: Hemant Agrawal [mailto:hemant.agrawal@nxp.com]
>> Sent: Thursday, January 19, 2017 1:23 PM
>> To: dev@dpdk.org
>> Cc: thomas.monjalon@6wind.com; Richardson, Bruce
>> <bruce.richardson@intel.com>; shreyansh.jain@nxp.com; Mcnamara, John
>> <john.mcnamara@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
>> jerin.jacob@caviumnetworks.com; Hemant Agrawal <hemant.agrawal@nxp.com>
>> Subject: [PATCHv5 02/33] doc: add dpaa2 nic details
>>
>> ...
>>
>> +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
>> +
>> + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
>> + "Network Interface Controller Drivers" document for more details on
>> + this new driver.
>> +
>> +* **Added a new driver for NXP DPAA2 Network PMD.**
>> +
>> + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
>> + "Network Interface Controller Drivers" document for more details on
>> + this new driver.
>>
>> New Features
>> ------------
>
> These additions should be after "New Features" and not before, if you do
> another revision you can fix it. If not it could be fixed on commit or I
> can fix it in the final Release note review.
>
> But overall the NIC guide is very good.
>
> Acked-by: John McNamara <john.mcnamara@intel.com>
>
>
I am doing next rev, so I will fix it.
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (3 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 02/33] doc: add dpaa2 nic details Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 19:07 ` Ferruh Yigit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
` (30 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Geoff Thorpe, Roy Pledge,
Hemant Agrawal
QBMAN, is a hardware block which interfaces with the other
accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
SoC for queue, buffer and packet scheduling.
This patch introduces a userspace driver for interfacing with
the QBMAN hw block.
The qbman-portal component provides APIs to do the low level
hardware bit twiddling for operations such as:
-initializing Qman software portals
-building and sending portal commands
-portal interrupt configuration and processing
This same/similar code is used in kernel and compat file is used
to make it working in user space.
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 3 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +-
drivers/Makefile | 1 +
drivers/common/Makefile | 36 +
drivers/common/dpaa2/Makefile | 36 +
drivers/common/dpaa2/qbman/Makefile | 53 +
drivers/common/dpaa2/qbman/include/compat.h | 403 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 157 ++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1090 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1492 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 274 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 167 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 382 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 70 +
.../dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map | 27 +
15 files changed, 4198 insertions(+), 1 deletion(-)
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map
diff --git a/config/common_base b/config/common_base
index b9fb8e2..a64fd8b 100644
--- a/config/common_base
+++ b/config/common_base
@@ -288,6 +288,9 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile Support Libraries for NXP DPAA2
+#
+CONFIG_RTE_LIBRTE_DPAA2_COMMON=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 66df54c..c57c340 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -40,3 +41,8 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
#
CONFIG_RTE_MAX_LCORE=8
CONFIG_RTE_MAX_NUMA_NODES=1
+
+#
+# Compile Support Libraries for DPAA2
+#
+CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
diff --git a/drivers/Makefile b/drivers/Makefile
index 81c03a8..d5580f6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -31,6 +31,7 @@
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..e5bfecb
--- /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_COMMON) += dpaa2
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
new file mode 100644
index 0000000..4960ebe
--- /dev/null
+++ b/drivers/common/dpaa2/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_COMMON) += qbman
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
new file mode 100644
index 0000000..a6f7ece
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -0,0 +1,53 @@
+# 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_qbman.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+
+EXPORT_MAP := rte_pmd_dpaa2_qbman_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += \
+ qbman_portal.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/common/dpaa2/qbman/include/compat.h b/drivers/common/dpaa2/qbman/include/compat.h
new file mode 100644
index 0000000..d321cc6
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/compat.h
@@ -0,0 +1,403 @@
+/* Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 HEADER_COMPAT_H
+#define HEADER_COMPAT_H
+
+#include <sched.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <net/ethernet.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <assert.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <error.h>
+#include <rte_atomic.h>
+
+/* The following definitions are primarily to allow the single-source driver
+ * interfaces to be included by arbitrary program code. Ie. for interfaces that
+ * are also available in kernel-space, these definitions provide compatibility
+ * with certain attributes and types used in those interfaces.
+ */
+
+/* Required compiler attributes */
+#define __user
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+#undef container_of
+#define container_of(ptr, type, member) ({ \
+ typeof(((type *)0)->member)(*__mptr) = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#ifdef ARRAY_SIZE
+#undef ARRAY_SIZE
+#endif
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/* Required types */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uint64_t dma_addr_t;
+typedef cpu_set_t cpumask_t;
+typedef u32 compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+/* I/O operations */
+static inline u32 in_be32(volatile void *__p)
+{
+ volatile u32 *p = __p;
+ return *p;
+}
+
+static inline void out_be32(volatile void *__p, u32 val)
+{
+ volatile u32 *p = __p;
+ *p = val;
+}
+
+/* Debugging */
+#define prflush(fmt, args...) \
+ do { \
+ printf(fmt, ##args); \
+ fflush(stdout); \
+ } while (0)
+#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args)
+#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args)
+#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args)
+#define pr_info(fmt, args...) prflush(fmt, ##args)
+
+#ifdef pr_debug
+#undef pr_debug
+#endif
+#define pr_debug(fmt, args...) {}
+#define might_sleep_if(c) {}
+#define msleep(x) {}
+#define WARN_ON(c, str) \
+do { \
+ static int warned_##__LINE__; \
+ if ((c) && !warned_##__LINE__) { \
+ pr_warn("%s\n", str); \
+ pr_warn("(%s:%d)\n", __FILE__, __LINE__); \
+ warned_##__LINE__ = 1; \
+ } \
+} while (0)
+#define QBMAN_BUG_ON(c) WARN_ON(c, "BUG")
+
+#define ALIGN(x, a) (((x) + ((typeof(x))(a) - 1)) & ~((typeof(x))(a) - 1))
+
+/****************/
+/* Linked-lists */
+/****************/
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_HEAD(n) \
+struct list_head n = { \
+ .prev = &n, \
+ .next = &n \
+}
+
+#define INIT_LIST_HEAD(p) \
+do { \
+ struct list_head *__p298 = (p); \
+ __p298->next = __p298; \
+ __p298->prev = __p298->next; \
+} while (0)
+#define list_entry(node, type, member) \
+ (type *)((void *)node - offsetof(type, member))
+#define list_empty(p) \
+({ \
+ const struct list_head *__p298 = (p); \
+ ((__p298->next == __p298) && (__p298->prev == __p298)); \
+})
+#define list_add(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->next = __l298->next; \
+ __p298->prev = __l298; \
+ __l298->next->prev = __p298; \
+ __l298->next = __p298; \
+} while (0)
+#define list_add_tail(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->prev = __l298->prev; \
+ __p298->next = __l298; \
+ __l298->prev->next = __p298; \
+ __l298->prev = __p298; \
+} while (0)
+#define list_for_each(i, l) \
+ for (i = (l)->next; i != (l); i = i->next)
+#define list_for_each_safe(i, j, l) \
+ for (i = (l)->next, j = i->next; i != (l); \
+ i = j, j = i->next)
+#define list_for_each_entry(i, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \
+ i = list_entry(i->name.next, typeof(*i), name))
+#define list_for_each_entry_safe(i, j, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name), \
+ j = list_entry(i->name.next, typeof(*j), name); \
+ &i->name != (l); \
+ i = j, j = list_entry(j->name.next, typeof(*j), name))
+#define list_del(i) \
+do { \
+ (i)->next->prev = (i)->prev; \
+ (i)->prev->next = (i)->next; \
+} while (0)
+
+/* Other miscellaneous interfaces our APIs depend on; */
+
+#define lower_32_bits(x) ((u32)(x))
+#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16))
+
+/* Compiler/type stuff */
+typedef unsigned int gfp_t;
+typedef uint32_t phandle;
+
+#define __iomem
+#define EINTR 4
+#define ENODEV 19
+#define GFP_KERNEL 0
+#define __raw_readb(p) (*(const volatile unsigned char *)(p))
+#define __raw_readl(p) (*(const volatile unsigned int *)(p))
+#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); }
+
+/* memcpy() stuff - when you know alignments in advance */
+#ifdef CONFIG_TRY_BETTER_MEMCPY
+static inline void copy_words(void *dest, const void *src, size_t sz)
+{
+ u32 *__dest = dest;
+ const u32 *__src = src;
+ size_t __sz = sz >> 2;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x3);
+ QBMAN_BUG_ON((unsigned long)src & 0x3);
+ QBMAN_BUG_ON(sz & 0x3);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_shorts(void *dest, const void *src, size_t sz)
+{
+ u16 *__dest = dest;
+ const u16 *__src = src;
+ size_t __sz = sz >> 1;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x1);
+ QBMAN_BUG_ON((unsigned long)src & 0x1);
+ QBMAN_BUG_ON(sz & 0x1);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_bytes(void *dest, const void *src, size_t sz)
+{
+ u8 *__dest = dest;
+ const u8 *__src = src;
+
+ while (sz--)
+ *(__dest++) = *(__src++);
+}
+#else
+#define copy_words memcpy
+#define copy_shorts memcpy
+#define copy_bytes memcpy
+#endif
+
+/* Completion stuff */
+#define DECLARE_COMPLETION(n) int n = 0
+#define complete(n) { *n = 1; }
+#define wait_for_completion(n) \
+do { \
+ while (!*n) { \
+ bman_poll(); \
+ qman_poll(); \
+ } \
+ *n = 0; \
+} while (0)
+
+/* Allocator stuff */
+#define kmalloc(sz, t) malloc(sz)
+#define vmalloc(sz) malloc(sz)
+#define kfree(p) { if (p) free(p); }
+static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused)
+{
+ void *ptr = malloc(sz);
+
+ if (ptr)
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
+{
+ void *p;
+
+ if (posix_memalign(&p, 4096, 4096))
+ return 0;
+ memset(p, 0, 4096);
+ return (unsigned long)p;
+}
+
+static inline void free_page(unsigned long p)
+{
+ free((void *)p);
+}
+
+/* Bitfield stuff. */
+#define BITS_PER_ULONG (sizeof(unsigned long) << 3)
+#define SHIFT_PER_ULONG (((1 << 5) == BITS_PER_ULONG) ? 5 : 6)
+#define BITS_MASK(idx) ((unsigned long)1 << ((idx) & (BITS_PER_ULONG - 1)))
+#define BITS_IDX(idx) ((idx) >> SHIFT_PER_ULONG)
+static inline unsigned long test_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ return *p & mask;
+}
+
+static inline int test_bit(int idx, volatile unsigned long *bits)
+{
+ return test_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void set_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p |= mask;
+}
+
+static inline void set_bit(int idx, volatile unsigned long *bits)
+{
+ set_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p &= ~mask;
+}
+
+static inline void clear_bit(int idx, volatile unsigned long *bits)
+{
+ clear_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline unsigned long test_and_set_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ unsigned long ret = test_bits(mask, p);
+
+ set_bits(mask, p);
+ return ret;
+}
+
+static inline int test_and_set_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ set_bit(idx, bits);
+ return ret;
+}
+
+static inline int test_and_clear_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ clear_bit(idx, bits);
+ return ret;
+}
+
+static inline int find_next_zero_bit(unsigned long *bits, int limit, int idx)
+{
+ while ((++idx < limit) && test_bit(idx, bits))
+ ;
+ return idx;
+}
+
+static inline int find_first_zero_bit(unsigned long *bits, int limit)
+{
+ int idx = 0;
+
+ while (test_bit(idx, bits) && (++idx < limit))
+ ;
+ return idx;
+}
+
+static inline u64 div64_u64(u64 n, u64 d)
+{
+ return n / d;
+}
+
+#define atomic_t rte_atomic32_t
+#define atomic_read(v) rte_atomic32_read(v)
+#define atomic_set(v, i) rte_atomic32_set(v, i)
+
+#define atomic_inc(v) rte_atomic32_add(v, 1)
+#define atomic_dec(v) rte_atomic32_sub(v, 1)
+
+#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v)
+#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v)
+
+#define atomic_inc_return(v) rte_atomic32_add_return(v, 1)
+#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1)
+#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
+
+#endif /* HEADER_COMPAT_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
new file mode 100644
index 0000000..bae019f
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
@@ -0,0 +1,157 @@
+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+typedef uint64_t dma_addr_t;
+
+/**
+ * DOC: QBMan basic structures
+ *
+ * The QBMan block descriptor, software portal descriptor and Frame descriptor
+ * are defined here.
+ *
+ */
+
+#define QMAN_REV_4000 0x04000000
+#define QMAN_REV_4100 0x04010000
+#define QMAN_REV_4101 0x04010001
+
+/**
+ * struct qbman_block_desc - qbman block descriptor structure
+ * @ccsr_reg_bar: CCSR register map.
+ * @irq_rerr: Recoverable error interrupt line.
+ * @irq_nrerr: Non-recoverable error interrupt line
+ *
+ * Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to.
+ */
+struct qbman_block_desc {
+ void *ccsr_reg_bar;
+ int irq_rerr;
+ int irq_nrerr;
+};
+
+enum qbman_eqcr_mode {
+ qman_eqcr_vb_ring = 2, /* Valid bit, with eqcr in ring mode */
+ qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */
+};
+
+/**
+ * struct qbman_swp_desc - qbman software portal descriptor structure
+ * @block: The QBMan instance.
+ * @cena_bar: Cache-enabled portal register map.
+ * @cinh_bar: Cache-inhibited portal register map.
+ * @irq: -1 if unused (or unassigned)
+ * @idx: SWPs within a QBMan are indexed. -1 if opaque to the user.
+ * @qman_version: the qman version.
+ * @eqcr_mode: Select the eqcr mode, currently only valid bit ring mode and
+ * valid bit array mode are supported.
+ *
+ * Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "MC bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering.
+ */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block;
+ uint8_t *cena_bar;
+ uint8_t *cinh_bar;
+ int irq;
+ int idx;
+ uint32_t qman_version;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/**
+ * struct qbman_fd - basci structure for qbman frame descriptor
+ * @words: for easier/faster copying the whole FD structure.
+ * @addr_lo: the lower 32 bits of the address in FD.
+ * @addr_hi: the upper 32 bits of the address in FD.
+ * @len: the length field in FD.
+ * @bpid_offset: represent the bpid and offset fields in FD. offset in
+ * the MS 16 bits, BPID in the LS 16 bits.
+ * @frc: frame context
+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
+ * @flc_lo: the lower 32bit of flow context.
+ * @flc_hi: the upper 32bits of flow context.
+ *
+ * Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ uint32_t bpid_offset;
+ uint32_t frc;
+ uint32_t ctrl;
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
new file mode 100644
index 0000000..a86ab31
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
@@ -0,0 +1,1090 @@
+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl_qbman_base.h>
+
+/**
+ * DOC - QBMan portal APIs to implement the following functions:
+ * - Initialize and destroy Software portal object.
+ * - Read and write Software portal interrupt registers.
+ * - Enqueue, including setting the enqueue descriptor, and issuing enqueue
+ * command etc.
+ * - Dequeue, including setting the dequeue descriptor, issuing dequeue command,
+ * parsing the dequeue response in DQRR and memeory, parsing the state change
+ * notifications etc.
+ * - Release, including setting the release descriptor, and issuing the buffer
+ * release command.
+ * - Acquire, acquire the buffer from the given buffer pool.
+ * - FQ management.
+ * - Channel management, enable/disable CDAN with or without context.
+ */
+
+/**
+ * qbman_swp_init() - Create a functional object representing the given
+ * QBMan portal descriptor.
+ * @d: the given qbman swp descriptor
+ *
+ * Return qbman_swp portal object for success, NULL if the object cannot
+ * be created.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
+
+/**
+ * qbman_swp_finish() - Create and destroy a functional object representing
+ * the given QBMan portal descriptor.
+ * @p: the qbman_swp object to be destroyed.
+ *
+ */
+void qbman_swp_finish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_get_desc() - Get the descriptor of the given portal object.
+ * @p: the given portal object.
+ *
+ * Return the descriptor for this portal.
+ */
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p);
+
+ /**************/
+ /* Interrupts */
+ /**************/
+
+/* EQCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_EQRI ((uint32_t)0x00000001)
+/* Enqueue command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_EQDI ((uint32_t)0x00000002)
+/* DQRR non-empty interrupt */
+#define QBMAN_SWP_INTERRUPT_DQRI ((uint32_t)0x00000004)
+/* RCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_RCRI ((uint32_t)0x00000008)
+/* Release command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_RCDI ((uint32_t)0x00000010)
+/* Volatile dequeue command interrupt */
+#define QBMAN_SWP_INTERRUPT_VDCI ((uint32_t)0x00000020)
+
+/**
+ * qbman_swp_interrupt_get_vanish() - Get the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISDR register.
+ */
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_vanish() - Set the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IDSR register.
+ */
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_read_status() - Get the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISR register.
+ */
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_clear_status() - Set the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_ISR register.
+ */
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_trigger() - Get the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IER register.
+ */
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_trigger() - Set the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IER register.
+ */
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_inhibit() - Get the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IIR register.
+ */
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_inhibit() - Set the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IIR register.
+ */
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/**
+ * struct qbman_result - structure for qbman dequeue response and/or
+ * notification.
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * possible qbman dequeue result.
+ */
+struct qbman_result {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* TODO:
+ *A DQRI interrupt can be generated when there are dequeue results on the
+ * portal's DQRR (this mechanism does not deal with "pull" dequeues to
+ * user-supplied 'storage' addresses). There are two parameters to this
+ * interrupt source, one is a threshold and the other is a timeout. The
+ * interrupt will fire if either the fill-level of the ring exceeds 'thresh', or
+ * if the ring has been non-empty for been longer than 'timeout' nanoseconds.
+ * For timeout, an approximation to the desired nanosecond-granularity value is
+ * made, so there are get and set APIs to allow the user to see what actual
+ * timeout is set (compared to the timeout that was requested).
+ */
+int qbman_swp_dequeue_thresh(struct qbman_swp *s, unsigned int thresh);
+int qbman_swp_dequeue_set_timeout(struct qbman_swp *s, unsigned int timeout);
+int qbman_swp_dequeue_get_timeout(struct qbman_swp *s, unsigned int *timeout);
+
+/* ------------------- */
+/* Push-mode dequeuing */
+/* ------------------- */
+
+/* The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+
+/**
+ * qbman_swp_push_get() - Get the push dequeue setup.
+ * @s: the software portal object.
+ * @channel_idx: the channel index to query.
+ * @enabled: returned boolean to show whether the push dequeue is enabled for
+ * the given channel.
+ */
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled);
+
+/**
+ * qbman_swp_push_set() - Enable or disable push dequeue.
+ * @s: the software portal object.
+ * @channel_idx: the channel index..
+ * @enable: enable or disable push dequeue.
+ *
+ * The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable);
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+/**
+ * struct qbman_pull_desc - the structure for pull dequeue descriptor
+ * @dont_manipulate_directly: the 6 32bit data to represent the whole
+ * possible settings for pull dequeue descriptor.
+ */
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+enum qbman_pull_type_e {
+ /* dequeue with priority precedence, respect intra-class scheduling */
+ qbman_pull_type_prio = 1,
+ /* dequeue with active FQ precedence, respect ICS */
+ qbman_pull_type_active,
+ /* dequeue with active FQ precedence, no ICS */
+ qbman_pull_type_active_noics
+};
+
+/**
+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the pull dequeue descriptor to be cleared.
+ */
+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
+
+/**
+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
+ * @d: the pull dequeue descriptor to be set.
+ * @storage: the pointer of the memory to store the dequeue result.
+ * @storage_phys: the physical address of the storage memory.
+ * @stash: to indicate whether write allocate is enabled.
+ *
+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute.
+ */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/**
+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued.
+ * @d: the pull dequeue descriptor to be set.
+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive.
+ */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
+ uint8_t numframes);
+/**
+ * qbman_pull_desc_set_token() - Set dequeue token for pull command
+ * @d: the dequeue descriptor
+ * @token: the token to be set
+ *
+ * token is the value that shows up in the dequeue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing a dequeue, and use any non-zero 'token' value
+ */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+/**
+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues.
+ * @fqid: the frame queue index of the given FQ.
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid);
+
+/**
+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues.
+ * @wqid: composed of channel id and wqid within the channel.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct);
+
+/* qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
+ * dequeues.
+ * @chid: the channel id to be dequeued.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct);
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object.
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls.
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry.
+ * @s: the software portal object.
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *p);
+
+/**
+ * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
+ * qbman_swp_dqrr_next().
+ * @s: the software portal object.
+ * @dq: the DQRR entry to be consumed.
+ */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct qbman_result *dq);
+
+/**
+ * qbman_get_dqrr_idx() - Get dqrr index from the given dqrr
+ * @dqrr: the given dqrr object.
+ *
+ * Return dqrr index.
+ */
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr);
+
+/**
+ * qbman_get_dqrr_from_idx() - Use index to get the dqrr entry from the
+ * given portal
+ * @s: the given portal.
+ * @idx: the dqrr index.
+ *
+ * Return dqrr entry object.
+ */
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/**
+ * qbman_result_has_new_result() - Check and get the dequeue response from the
+ * dq storage memory set in pull dequeue command
+ * @s: the software portal object.
+ * @dq: the dequeue result read from the memory.
+ *
+ * Only used for user-provided storage of dequeue results, not DQRR. For
+ * efficiency purposes, the driver will perform any required endianness
+ * conversion to ensure that the user's dequeue result storage is in host-endian
+ * format (whether or not that is the same as the little-endian format that
+ * hardware DMA'd to the user's storage). As such, once the user has called
+ * qbman_result_has_new_result() and been returned a valid dequeue result,
+ * they should not call it again on the same memory location (except of course
+ * if another dequeue command has been executed to produce a new result to that
+ * location).
+ *
+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
+ * dequeue result.
+ */
+int qbman_result_has_new_result(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/**
+ * qbman_result_is_DQ() - check the dequeue result is a dequeue response or not
+ * @dq: the dequeue result to be checked.
+ *
+ * DQRR entries may contain non-dequeue results, ie. notifications
+ */
+int qbman_result_is_DQ(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
+ * @dq: the dequeue result to be checked.
+ *
+ * All the non-dequeue results (FQDAN/CDAN/CSCN/...) are "state change
+ * notifications" of one type or another. Some APIs apply to all of them, of the
+ * form qbman_result_SCN_***().
+ */
+static inline int qbman_result_is_SCN(const struct qbman_result *dq)
+{
+ return !qbman_result_is_DQ(dq);
+}
+
+/* Recognise different notification types, only required if the user allows for
+ * these to occur, and cares about them when they do.
+ */
+
+/**
+ * qbman_result_is_FQDAN() - Check for FQ Data Availability
+ * @dq: the qbman_result object.
+ *
+ * Return 1 if this is FQDAN.
+ */
+int qbman_result_is_FQDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CDAN() - Check for Channel Data Availability
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CDAN.
+ */
+int qbman_result_is_CDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CSCN() - Check for Congestion State Change
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CSCN.
+ */
+int qbman_result_is_CSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_BPSCN() - Check for Buffer Pool State Change.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is BPSCN.
+ */
+int qbman_result_is_BPSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CGCU() - Check for Congestion Group Count Update.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CGCU.
+ */
+int qbman_result_is_CGCU(const struct qbman_result *dq);
+
+/* Frame queue state change notifications; (FQDAN in theory counts too as it
+ * leaves a FQ parked, but it is primarily a data availability notification)
+ */
+
+/**
+ * qbman_result_is_FQRN() - Check for FQ Retirement Notification.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRN.
+ */
+int qbman_result_is_FQRN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQRNI() - Check for FQ Retirement Immediate
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRNI.
+ */
+int qbman_result_is_FQRNI(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQPN() - Check for FQ Park Notification
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQPN.
+ */
+int qbman_result_is_FQPN(const struct qbman_result *dq);
+
+/* Parsing frame dequeue results (qbman_result_is_DQ() must be TRUE)
+ */
+/* FQ empty */
+#define QBMAN_DQ_STAT_FQEMPTY 0x80
+/* FQ held active */
+#define QBMAN_DQ_STAT_HELDACTIVE 0x40
+/* FQ force eligible */
+#define QBMAN_DQ_STAT_FORCEELIGIBLE 0x20
+/* Valid frame */
+#define QBMAN_DQ_STAT_VALIDFRAME 0x10
+/* FQ ODP enable */
+#define QBMAN_DQ_STAT_ODPVALID 0x04
+/* Volatile dequeue */
+#define QBMAN_DQ_STAT_VOLATILE 0x02
+/* volatile dequeue command is expired */
+#define QBMAN_DQ_STAT_EXPIRED 0x01
+
+/**
+ * qbman_result_DQ_flags() - Get the STAT field of dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the state field.
+ */
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_is_pull() - Check whether the dq response is from a pull
+ * command.
+ * @dq: the dequeue result.
+ *
+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
+ */
+static inline int qbman_result_DQ_is_pull(const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_VOLATILE);
+}
+
+/**
+ * qbman_result_DQ_is_pull_complete() - Check whether the pull command is
+ * completed.
+ * @dq: the dequeue result.
+ *
+ * Return boolean.
+ */
+static inline int qbman_result_DQ_is_pull_complete(
+ const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_EXPIRED);
+}
+
+/**
+ * qbman_result_DQ_seqnum() - Get the seqnum field in dequeue response
+ * seqnum is valid only if VALIDFRAME flag is TRUE
+ * @dq: the dequeue result.
+ *
+ * Return seqnum.
+ */
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_odpid() - Get the seqnum field in dequeue response
+ * odpid is valid only if ODPVAILD flag is TRUE.
+ * @dq: the dequeue result.
+ *
+ * Return odpid.
+ */
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqid() - Get the fqid in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return fqid.
+ */
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_byte_count() - Get the byte count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the byte count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_frame_count - Get the frame count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqd_ctx() - Get the frame queue context in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame queue context.
+ */
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fd() - Get the frame descriptor in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame descriptor.
+ */
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq);
+
+/* State-change notifications (FQDAN/CDAN/CSCN/...). */
+
+/**
+ * qbman_result_SCN_state() - Get the state field in State-change notification
+ * @scn: the state change notification.
+ *
+ * Return the state in the notifiation.
+ */
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid() - Get the resource id from the notification
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_ctx() - get the context from the notification
+ * @scn: the state change notification.
+ *
+ * Return the context.
+ */
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_state_in_mem() - Get the state in notification written
+ * in memory
+ * @scn: the state change notification.
+ *
+ * Return the state.
+ */
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid_in_mem() - Get the resource id in notification written
+ * in memory.
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn);
+
+/* Type-specific "resource IDs". Mainly for illustration purposes, though it
+ * also gives the appropriate type widths.
+ */
+/* Get the FQID from the FQDAN */
+#define qbman_result_FQDAN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRN */
+#define qbman_result_FQRN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRNI */
+#define qbman_result_FQRNI_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQPN */
+#define qbman_result_FQPN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the channel ID from the CDAN */
+#define qbman_result_CDAN_cid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+/* Get the CGID from the CSCN */
+#define qbman_result_CSCN_cgid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+
+/**
+ * qbman_result_bpscn_bpid() - Get the bpid from BPSCN
+ * @scn: the state change notification.
+ *
+ * Return the buffer pool id.
+ */
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_has_free_bufs() - Check whether there are free
+ * buffers in the pool from BPSCN.
+ * @scn: the state change notification.
+ *
+ * Return the number of free buffers.
+ */
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_depleted() - Check BPSCN to see whether the
+ * buffer pool is depleted.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool depletion.
+ */
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_surplus() - Check BPSCN to see whether the buffer
+ * pool is surplus or not.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool surplus.
+ */
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_ctx() - Get the BPSCN CTX from BPSCN message
+ * @scn: the state change notification.
+ *
+ * Return the BPSCN context.
+ */
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn);
+
+/* Parsing CGCU */
+/**
+ * qbman_result_cgcu_cgid() - Check CGCU resouce id, i.e. cgid
+ * @scn: the state change notification.
+ *
+ * Return the CGCU resource id.
+ */
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_cgcu_icnt() - Get the I_CNT from CGCU
+ * @scn: the state change notification.
+ *
+ * Return instantaneous count in the CGCU notification.
+ */
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+/**
+ * struct qbman_eq_desc - structure of enqueue descriptor
+ * @dont_manipulate_directly: the 8 32bit data to represent the whole
+ * possible qbman enqueue setting in enqueue descriptor.
+ */
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+/**
+ * struct qbman_eq_response - structure of enqueue response
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * enqueue response.
+ */
+struct qbman_eq_response {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/**
+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the given enqueue descriptor.
+ */
+void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+
+/**
+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+/**
+ * qbman_eq_desc_set_orp() - Set order-resotration in the enqueue descriptor
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ * @incomplete: indiates whether this is the last fragments using the same
+ * sequeue number.
+ */
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete);
+
+/**
+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+
+/**
+ * qbman_eq_desc_set_orp_nesn() - advance NESN (Next Expected Sequence Number)
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+/**
+ * qbman_eq_desc_set_response() - Set the enqueue response info.
+ * @d: the enqueue descriptor
+ * @storage_phys: the physical address of the enqueue response in memory.
+ * @stash: indicate that the write allocation enabled or not.
+ *
+ * In the case where an enqueue response is DMA'd, this determines where that
+ * response should go. (The physical/DMA address is given for hardware's
+ * benefit, but software should interpret it as a "struct qbman_eq_response"
+ * data structure.) 'stash' controls whether or not the write to main-memory
+ * expresses a cache-warming attribute.
+ */
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash);
+
+/**
+ * qbman_eq_desc_set_token() - Set token for the enqueue command
+ * @d: the enqueue descriptor
+ * @token: the token to be set.
+ *
+ * token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value.
+ */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token);
+
+/**
+ * Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+/**
+ * qbman_eq_desc_set_fq() - Set Frame Queue id for the enqueue command
+ * @d: the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued.
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid);
+
+/**
+ * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command.
+ * @d: the enqueue descriptor
+ * @qdid: the id of the queuing destination to be enqueued.
+ * @qd_bin: the queuing destination bin
+ * @qd_prio: the queuing destination priority.
+ */
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/**
+ * qbman_eq_desc_set_eqdi() - enable/disable EQDI interrupt
+ * @d: the enqueue descriptor
+ * @enable: boolean to enable/disable EQDI
+ *
+ * Determines whether or not the portal's EQDI interrupt source should be
+ * asserted after the enqueue command is completed.
+ */
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable);
+
+/**
+ * qbman_eq_desc_set_dca() - Set DCA mode in the enqueue command.
+ * @d: the enqueue descriptor.
+ * @enable: enabled/disable DCA mode.
+ * @dqrr_idx: DCAP_CI, the DCAP consumer index.
+ * @park: determine the whether park the FQ or not
+ *
+ * Determines whether or not a portal DQRR entry should be consumed once the
+ * enqueue command is completed. (And if so, and the DQRR entry corresponds to a
+ * held-active (order-preserving) FQ, whether the FQ should be parked instead of
+ * being rescheduled.)
+ */
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park);
+
+/**
+ * qbman_swp_enqueue() - Issue an enqueue command.
+ * @s: the software portal used for enqueue.
+ * @d: the enqueue descriptor.
+ * @fd: the frame descriptor to be enqueued.
+ *
+ * Please note that 'fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".
+ *
+ * Return 0 for a successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd);
+
+/* TODO:
+ * qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt.
+ * @s: the software portal.
+ * @thresh: the threshold to trigger the EQRI interrupt.
+ *
+ * An EQRI interrupt can be generated when the fill-level of EQCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_enqueue_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+/**
+ * struct qbman_release_desc - The structure for buffer release descriptor
+ * @dont_manipulate_directly: the 32bit data to represent the whole
+ * possible settings of qbman release descriptor.
+ */
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/**
+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_clear(struct qbman_release_desc *d);
+
+/**
+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid);
+
+/**
+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
+ * interrupt source should be asserted after the release command is completed.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+
+/**
+ * qbman_swp_release() - Issue a buffer release command.
+ * @s: the software portal object.
+ * @d: the release descriptor.
+ * @buffers: a pointer pointing to the buffer address to be released.
+ * @num_buffers: number of buffers to be released, must be less than 8.
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+/* TODO:
+ * qbman_swp_release_thresh() - Set threshold for RCRI interrupt
+ * @s: the software portal.
+ * @thresh: the threshold.
+ * An RCRI interrupt can be generated when the fill-level of RCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_release_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+/**
+ * qbman_swp_acquire() - Issue a buffer acquire command.
+ * @s: the software portal object.
+ * @bpid: the buffer pool index.
+ * @buffers: a pointer pointing to the acquired buffer address|es.
+ * @num_buffers: number of buffers to be acquired, must be less than 8.
+ *
+ * Return 0 for success, or negative error code if the acquire command
+ * fails.
+ */
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+
+ /*****************/
+ /* FQ management */
+ /*****************/
+/**
+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be scheduled.
+ *
+ * There are a couple of different ways that a FQ can end up parked state,
+ * This schedules it.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be forced.
+ *
+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
+ * and thus be available for selection by any channel-dequeuing behaviour (push
+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
+ * empty at the time this happens, the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * These functions change the FQ flow-control stuff between XON/XOFF. (The
+ * default is XON.) This setting doesn't affect enqueues to the FQ, just
+ * dequeues. XOFF FQs will remain in the tenatively-scheduled state, even when
+ * non-empty, meaning they won't be selected for scheduled dequeuing. If a FQ is
+ * changed to XOFF after it had already become truly-scheduled to a channel, and
+ * a pull dequeue of that channel occurs that selects that FQ for dequeuing,
+ * then the resulting dq_entry will have no FD. (qbman_result_DQ_fd() will
+ * return NULL.)
+ */
+/**
+ * qbman_swp_fq_xon() - XON the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid);
+/**
+ * qbman_swp_fq_xoff() - XOFF the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid);
+
+ /**********************/
+ /* Channel management */
+ /**********************/
+
+/**
+ * If the user has been allocated a channel object that is going to generate
+ * CDANs to another channel, then these functions will be necessary.
+ * CDAN-enabled channels only generate a single CDAN notification, after which
+ * it they need to be reenabled before they'll generate another. (The idea is
+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
+ * reenable step.) Each function generates a distinct command to hardware, so a
+ * combination function is provided if the user wishes to modify the "context"
+ * (which shows up in each CDAN message) each time they reenable, as a single
+ * command to hardware.
+ */
+
+/**
+ * qbman_swp_CDAN_set_context() - Set CDAN context
+ * @s: the software portal object.
+ * @channelid: the channel index.
+ * @ctx: the context to be set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+
+/**
+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_disable() - disable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ * @ctx: the context set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ uint8_t burst_index);
+int qbman_swp_flush_ring(struct qbman_swp *s);
+void qbman_sync(void);
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send);
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+int qbman_get_version(void);
+#endif /* !_FSL_QBMAN_PORTAL_H */
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
new file mode 100644
index 0000000..ccfe07d
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.c
@@ -0,0 +1,1492 @@
+/* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQCR_PI 0x800
+#define QBMAN_CINH_SWP_EQCR_CI 0x840
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DQPI 0xa00
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+#define QBMAN_CINH_SWP_ISR 0xe00
+#define QBMAN_CINH_SWP_IER 0xe40
+#define QBMAN_CINH_SWP_ISDR 0xe80
+#define QBMAN_CINH_SWP_IIR 0xec0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+#define QBMAN_CENA_SWP_EQCR_CI 0x840
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
+
+/* QBMan FQ management command codes */
+#define QBMAN_FQ_SCHEDULE 0x48
+#define QBMAN_FQ_FORCE 0x49
+#define QBMAN_FQ_XON 0x4d
+#define QBMAN_FQ_XOFF 0x4e
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init()
+ */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_eq_dca_idx;
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+struct qb_attr_code code_sdqcr_dqsrc = QB_CODE(0, 0, 16);
+
+/* We need to keep track of which SWP triggered a pull command
+ * so keep an array of portal IDs and use the token field to
+ * be able to find the proper portal
+ */
+#define MAX_QBMAN_PORTALS 35
+static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
+
+uint32_t qman_version;
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has.
+ *
+ * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
+ * valid-bits, so we need to support a workaround where we don't trust
+ * valid-bits when detecting new entries until any stale ring entries have been
+ * overwritten at least once. The idea is that we read PI for the first few
+ * entries, then switch to valid-bit after that. The trick is to clear the
+ * bug-work-around boolean once the PI wraps around the ring for the first time.
+ *
+ * Note: this still carries a slight additional cost once the decrementer hits
+ * zero.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ uint32_t eqcr_pi;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = *d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
+ atomic_set(&p->vdq.busy, 1);
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ qman_version = p->desc.qman_version;
+ if ((qman_version & 0xFFFF0000) < QMAN_REV_4100) {
+ p->dqrr.dqrr_size = 4;
+ p->dqrr.reset_bug = 1;
+ /* Set size of DQRR to 4, encoded in 2 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 2);
+ } else {
+ p->dqrr.dqrr_size = 8;
+ p->dqrr.reset_bug = 0;
+ /* Set size of DQRR to 8, encoded in 3 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 3);
+ }
+
+ ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
+ if (ret) {
+ kfree(p);
+ pr_err("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ /* SDQCR needs to be initialized to 0 when no channels are
+ * being dequeued from or else the QMan HW will indicate an
+ * error. The values that were calculated above will be
+ * applied when dequeues from a specific channel are enabled
+ */
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
+ eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
+ p->eqcr.pi = eqcr_pi & 0xF;
+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
+ p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & 0xF;
+ p->eqcr.available = QBMAN_EQCR_SIZE - qm_cyc_diff(QBMAN_EQCR_SIZE,
+ p->eqcr.ci, p->eqcr.pi);
+
+ portal_idx_map[p->desc.idx] = p;
+ return p;
+}
+
+void qbman_swp_finish(struct qbman_swp *p)
+{
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ qbman_swp_sys_finish(&p->sys);
+ portal_idx_map[p->desc.idx] = NULL;
+ kfree(p);
+}
+
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
+{
+ return &p->desc;
+}
+
+/**************/
+/* Interrupts */
+/**************/
+
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
+}
+
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
+}
+
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
+}
+
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
+}
+
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
+}
+
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
+}
+
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
+}
+
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
+#endif
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so.
+ */
+ QBMAN_BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ qbman_cena_invalidate_prefetch(&p->sys,
+ QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_eqdi = QB_CODE(0, 3, 1);
+static struct qb_attr_code code_eq_dca_en = QB_CODE(0, 15, 1);
+static struct qb_attr_code code_eq_dca_pk = QB_CODE(0, 14, 1);
+/* Can't set code_eq_dca_idx width. Need qman version. Read at runtime */
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_orp_is_nesn = QB_CODE(0, 31, 1);
+static struct qb_attr_code code_eq_orp_nlis = QB_CODE(0, 30, 1);
+static struct qb_attr_code code_eq_orp_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_eq_opr_id = QB_CODE(1, 0, 16);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
+static struct qb_attr_code code_eq_rsp_id = QB_CODE(5, 24, 8);
+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
+
+enum qbman_eq_cmd_e {
+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, !!incomplete);
+}
+
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 0);
+}
+
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 1);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
+}
+
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_rsp_id, cl, (uint32_t)token);
+}
+
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 0);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, fqid);
+}
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_eqdi, cl, !!enable);
+}
+
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_dca_en, cl, !!enable);
+ if (enable) {
+ qb_attr_code_encode(&code_eq_dca_pk, cl, !!park);
+ qb_attr_code_encode(&code_eq_dca_idx, cl, dqrr_idx);
+ }
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+
+ pr_debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ return 0;
+}
+
+static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ return 0;
+}
+
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ __attribute__((unused)) uint8_t burst_index)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR((s->eqcr.pi/* +burst_index */) & 7));
+ /* word_copy(&p[1], &cl[1], 7); */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ /* word_copy(&p[8], fd, sizeof(*fd) >> 2); */
+ memcpy(&p[8], fd, sizeof(struct qbman_fd));
+
+ /* lwsync(); */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+
+ return 0;
+}
+
+int qbman_swp_flush_ring(struct qbman_swp *s)
+{
+ void *ptr = s->sys.addr_cena;
+
+ dcbf((uint64_t)ptr);
+ dcbf((uint64_t)ptr + 0x40);
+ dcbf((uint64_t)ptr + 0x80);
+ dcbf((uint64_t)ptr + 0xc0);
+ dcbf((uint64_t)ptr + 0x100);
+ dcbf((uint64_t)ptr + 0x140);
+ dcbf((uint64_t)ptr + 0x180);
+ dcbf((uint64_t)ptr + 0x1c0);
+
+ return 0;
+}
+
+void qbman_sync(void)
+{
+ lwsync();
+}
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ if (s->sys.eqcr_mode == qman_eqcr_vb_array)
+ return qbman_swp_enqueue_array_mode(s, d, fd);
+ else /* Use ring mode by default */
+ return qbman_swp_enqueue_ring_mode(s, d, fd);
+}
+
+/*************************/
+/* Static (push) dequeue */
+/*************************/
+
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
+{
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ *enabled = (int)qb_attr_code_decode(&code, &s->sdq);
+}
+
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
+{
+ uint16_t dqsrc;
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ qb_attr_code_encode(&code, &s->sdq, !!enable);
+ /* Read make the complete src map. If no channels are enabled
+ * the SDQCR must be 0 or else QMan will assert errors
+ */
+ dqsrc = (uint16_t)qb_attr_code_decode(&code_sdqcr_dqsrc, &s->sdq);
+ if (dqsrc != 0)
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
+ else
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
+
+enum qb_pull_dt_e {
+ qb_pull_dt_channel,
+ qb_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command)
+ */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ qb_attr_code_encode(&code_pull_rls, cl, 1);
+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ QBMAN_BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_workqueue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, wqid);
+}
+
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_channel);
+ qb_attr_code_encode(&code_pull_dqsource, cl, chid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
+ return -EBUSY;
+ }
+ s->vdq.storage = *(void **)&cl[4];
+ /* We use portal index +1 as token so that 0 still indicates
+ * that the result isn't valid yet.
+ */
+ qb_attr_code_encode(&code_pull_token, cl, s->desc.idx + 1);
+ p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ word_copy(&p[1], &cl[1], 3);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+static struct qb_attr_code code_dqrr_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_dqrr_odpid = QB_CODE(1, 0, 16);
+/* static struct qb_attr_code code_dqrr_tok = QB_CODE(1, 24, 8); */
+static struct qb_attr_code code_dqrr_fqid = QB_CODE(2, 0, 24);
+static struct qb_attr_code code_dqrr_byte_count = QB_CODE(4, 0, 32);
+static struct qb_attr_code code_dqrr_frame_count = QB_CODE(5, 0, 24);
+static struct qb_attr_code code_dqrr_ctx_lo = QB_CODE(6, 0, 32);
+
+#define QBMAN_RESULT_DQ 0x60
+#define QBMAN_RESULT_FQRN 0x21
+#define QBMAN_RESULT_FQRNI 0x22
+#define QBMAN_RESULT_FQPN 0x24
+#define QBMAN_RESULT_FQDAN 0x25
+#define QBMAN_RESULT_CDAN 0x26
+#define QBMAN_RESULT_CSCN_MEM 0x27
+#define QBMAN_RESULT_CGCU 0x28
+#define QBMAN_RESULT_BPSCN 0x29
+#define QBMAN_RESULT_CSCN_WQ 0x2a
+
+static struct qb_attr_code code_dqpi_pi = QB_CODE(0, 0, 4);
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ uint32_t verb;
+ uint32_t response_verb;
+ uint32_t flags;
+ const struct qbman_result *dq;
+ const uint32_t *p;
+
+ /* Before using valid-bit to detect if something is there, we have to
+ * handle the case of the DQRR reset bug...
+ */
+ if (unlikely(s->dqrr.reset_bug)) {
+ /* We pick up new entries by cache-inhibited producer index,
+ * which means that a non-coherent mapping would require us to
+ * invalidate and read *only* once that PI has indicated that
+ * there's an entry here. The first trip around the DQRR ring
+ * will be much less efficient than all subsequent trips around
+ * it...
+ */
+ uint32_t dqpi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI);
+ uint32_t pi = qb_attr_code_decode(&code_dqpi_pi, &dqpi);
+ /* there are new entries iff pi != next_idx */
+ if (pi == s->dqrr.next_idx)
+ return NULL;
+ /* if next_idx is/was the last ring index, and 'pi' is
+ * different, we can disable the workaround as all the ring
+ * entries have now been DMA'd to so valid-bit checking is
+ * repaired. Note: this logic needs to be based on next_idx
+ * (which increments one at a time), rather than on pi (which
+ * can burst and wrap-around between our snapshots of it).
+ */
+ QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
+ pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
+ s->dqrr.next_idx, pi);
+ s->dqrr.reset_bug = 0;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ }
+ dq = qbman_cena_read_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
+ return NULL;
+
+ /* There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found.
+ */
+ s->dqrr.next_idx++;
+ if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
+ s->dqrr.next_idx = 0;
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+ }
+ /* If this is the final response to a volatile dequeue command
+ * indicate that the vdq is no longer busy.
+ */
+ flags = qbman_result_DQ_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_RESULT_DQ) &&
+ (flags & QBMAN_DQ_STAT_VOLATILE) &&
+ (flags & QBMAN_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+int qbman_result_has_new_result(__attribute__((unused)) struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* Entry is valid - overwrite token back to 0 so
+ * a) If this memory is reused tokesn will be 0
+ * b) If someone calls "has_new_result()" again on this entry it
+ * will not appear to be new
+ */
+ qb_attr_code_encode(&code_dqrr_tok_detect, &p[1], 0);
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice...
+ */
+ make_le32_n(p, 16);
+ return 1;
+}
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* TODO: Remove qbman_swp from parameters and make it a local
+ * once we've tested the reserve portal map change
+ */
+ s = portal_idx_map[token - 1];
+ /* When token is set it indicates that VDQ command has been fetched
+ * by qbman and is working on it. It is safe for software to issue
+ * another VDQ command, so incrementing the busy variable.
+ */
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
+ return 1;
+}
+
+/********************************/
+/* Categorising qbman results */
+/********************************/
+
+static struct qb_attr_code code_result_in_mem =
+ QB_CODE(0, QBMAN_RESULT_VERB_OFFSET_IN_MEM, 7);
+
+static inline int __qbman_result_is_x(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return (response_verb == x);
+}
+
+static inline int __qbman_result_is_x_in_mem(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_result_in_mem, p);
+
+ return (response_verb == x);
+}
+
+int qbman_result_is_DQ(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
+}
+
+int qbman_result_is_FQDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
+}
+
+int qbman_result_is_CDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
+}
+
+int qbman_result_is_CSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CSCN_MEM) ||
+ __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
+}
+
+int qbman_result_is_BPSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_BPSCN);
+}
+
+int qbman_result_is_CGCU(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CGCU);
+}
+
+int qbman_result_is_FQRN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRN);
+}
+
+int qbman_result_is_FQRNI(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRNI);
+}
+
+int qbman_result_is_FQPN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_result_is_DQ() is TRUE */
+
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_seqnum, p);
+}
+
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_odpid, p);
+}
+
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_fqid, p);
+}
+
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_byte_count, p);
+}
+
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_frame_count, p);
+}
+
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(dq);
+
+ return qb_attr_code_decode_64(&code_dqrr_ctx_lo, p);
+}
+
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct qbman_fd *)&p[8];
+}
+
+/**************************************/
+/* Parsing state-change notifications */
+/**************************************/
+
+static struct qb_attr_code code_scn_state = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_scn_rid = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_scn_state_in_mem =
+ QB_CODE(0, SCN_STATE_OFFSET_IN_MEM, 8);
+static struct qb_attr_code code_scn_rid_in_mem =
+ QB_CODE(1, SCN_RID_OFFSET_IN_MEM, 24);
+static struct qb_attr_code code_scn_ctx_lo = QB_CODE(2, 0, 32);
+
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state, p);
+}
+
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return qb_attr_code_decode(&code_scn_rid, p);
+}
+
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(scn);
+
+ return qb_attr_code_decode_64(&code_scn_ctx_lo, p);
+}
+
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state_in_mem, p);
+}
+
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+ uint32_t result_rid;
+
+ result_rid = qb_attr_code_decode(&code_scn_rid_in_mem, p);
+ return make_le24(result_rid);
+}
+
+/*****************/
+/* Parsing BPSCN */
+/*****************/
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0x3FFF;
+}
+
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
+{
+ return !(int)(qbman_result_SCN_state_in_mem(scn) & 0x1);
+}
+
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x2);
+}
+
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x4);
+}
+
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)make_le32(ctx_hi) << 32 |
+ (uint64_t)make_le32(ctx_lo));
+}
+
+/*****************/
+/* Parsing CGCU */
+/*****************/
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0xFFFF;
+}
+
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)(make_le32(ctx_hi) & 0xFF) << 32) |
+ (uint64_t)make_le32(ctx_lo);
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_rcdi = QB_CODE(0, 6, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_rcdi, cl, !!enable);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+
+ pr_debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers.
+ */
+ lwsync();
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t rslt, num;
+
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ QBMAN_BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
+
+/*****************/
+/* FQ management */
+/*****************/
+
+static struct qb_attr_code code_fqalt_fqid = QB_CODE(1, 0, 32);
+
+static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
+ uint8_t alt_fq_verb)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ qb_attr_code_encode(&code_fqalt_fqid, p, fqid);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | alt_fq_verb);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != alt_fq_verb);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
+ fqid, alt_fq_verb, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
+}
+
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
+}
+
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
+}
+
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
+}
+
+/**********************/
+/* Channel management */
+/**********************/
+
+static struct qb_attr_code code_cdan_cid = QB_CODE(0, 16, 12);
+static struct qb_attr_code code_cdan_we = QB_CODE(1, 0, 8);
+static struct qb_attr_code code_cdan_en = QB_CODE(1, 8, 1);
+static struct qb_attr_code code_cdan_ctx_lo = QB_CODE(2, 0, 32);
+
+/* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
+ * would be irresponsible to expose it.
+ */
+#define CODE_CDAN_WE_EN 0x1
+#define CODE_CDAN_WE_CTX 0x4
+
+static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
+ uint8_t we_mask, uint8_t cdan_en,
+ uint64_t ctx)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_cdan_cid, p, channelid);
+ qb_attr_code_encode(&code_cdan_we, p, we_mask);
+ qb_attr_code_encode(&code_cdan_en, p, cdan_en);
+ qb_attr_code_encode_64(&code_cdan_ctx_lo, (uint64_t *)p, ctx);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_WQCHAN_CONFIGURE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p)
+ != QBMAN_WQCHAN_CONFIGURE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("CDAN cQID %d failed: code = 0x%02x\n",
+ channelid, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_CTX,
+ 0, ctx);
+}
+
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 1, 0);
+}
+
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 0, 0);
+}
+
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
+ 1, ctx);
+}
+
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr)
+{
+ return QBMAN_IDX_FROM_DQRR(dqrr);
+}
+
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
+{
+ struct qbman_result *dq;
+
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
+ return dq;
+}
+
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+ int sent = 0;
+ int i;
+ int initial_pi = s->eqcr.pi;
+ uint64_t start_pointer;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ if (!diff)
+ goto done;
+ s->eqcr.available += diff;
+ }
+
+ /* we are trying to send frames_to_send,
+ * if we have enough space in the ring
+ */
+ while (s->eqcr.available && frames_to_send--) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+ /* Write command (except of first byte) and FD */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ memcpy(&p[8], &fd[sent], sizeof(struct qbman_fd));
+
+ initial_pi++;
+ initial_pi &= 0xF;
+ s->eqcr.available--;
+ sent++;
+ }
+
+done:
+ initial_pi = s->eqcr.pi;
+ lwsync();
+
+ /* in order for flushes to complete faster:
+ * we use a following trick: we record all lines in 32 bit word
+ */
+
+ initial_pi = s->eqcr.pi;
+ for (i = 0; i < sent; i++) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ initial_pi++;
+ initial_pi &= 0xF;
+
+ if (!(initial_pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ initial_pi = s->eqcr.pi;
+
+ /* We need to flush all the lines but without
+ * load/store operations between them.
+ * We assign start_pointer before we start loop so that
+ * in loop we do not read it from memory
+ */
+ start_pointer = (uint64_t)s->sys.addr_cena;
+ for (i = 0; i < sent; i++) {
+ p = (uint32_t *)(start_pointer
+ + QBMAN_CENA_SWP_EQCR(initial_pi & 7));
+ dcbf((uint64_t)p);
+ initial_pi++;
+ initial_pi &= 0xF;
+ }
+
+ /* Update producer index for the next call */
+ s->eqcr.pi = initial_pi;
+
+ return sent;
+}
+
+int qbman_get_version(void)
+{
+ return qman_version;
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.h b/drivers/common/dpaa2/qbman/qbman_portal.h
new file mode 100644
index 0000000..fe93354
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.h
@@ -0,0 +1,274 @@
+/* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_private.h"
+#include <fsl_qbman_portal.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* QBMan DQRR size is set at runtime in qbman_portal.c */
+
+#define QBMAN_EQCR_SIZE 8
+
+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return last - first;
+ return (2 * ringsize) + last - first;
+}
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ struct qbman_swp_desc desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here.
+ */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * to whether or not a command can be submitted, not whether or
+ * not a previously-submitted command is still executing. In
+ * other words, once proof is seen that the previously-submitted
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ /* We need to determine when vdq is no longer busy. This depends
+ * on whether the "busy" (last-submitted) dequeue command is
+ * targeting DQRR or main-memory, and detected is based on the
+ * presence of the dequeue command's "token" showing up in
+ * dequeue entries in DQRR or main-memory (respectively).
+ */
+ struct qbman_result *storage; /* NULL if DQRR */
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ uint8_t dqrr_size;
+ int reset_bug;
+ } dqrr;
+ struct {
+ uint32_t pi;
+ uint32_t pi_vb;
+ uint32_t ci;
+ int available;
+ } eqcr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete).
+ */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and DPAA2 QBMan is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Some pre-defined codes */
+extern struct qb_attr_code code_generic_verb;
+extern struct qb_attr_code code_generic_rslt;
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+#define QB_CODE_NULL \
+ QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
+
+/* Rotate a code "ms", meaning that it moves from less-significant bytes to
+ * more-significant, from less-significant words to more-significant, etc. The
+ * "ls" version does the inverse, from more-significant towards
+ * less-significant.
+ */
+static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ code->lsoffset += bits;
+ while (code->lsoffset > 31) {
+ code->word++;
+ code->lsoffset -= 32;
+ }
+}
+
+static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ /* Don't be fooled, this trick should work because the types are
+ * unsigned. So the case that interests the while loop (the rotate has
+ * gone too far and the word count needs to compensate for it), is
+ * manifested when lsoffset is negative. But that equates to a really
+ * large unsigned value, starting with lots of "F"s. As such, we can
+ * continue adding 32 back to it until it wraps back round above zero,
+ * to a value of 31 or less...
+ */
+ code->lsoffset -= bits;
+ while (code->lsoffset > 31) {
+ code->word--;
+ code->lsoffset += 32;
+ }
+}
+
+/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
+#define qb_attr_code_for_ms(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ms(code, bits))
+#define qb_attr_code_for_ls(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ls(code, bits))
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
+}
+
+static inline uint64_t qb_attr_code_decode_64(const struct qb_attr_code *code,
+ const uint64_t *cacheline)
+{
+ return cacheline[code->word / 2];
+}
+
+/* encode a field to a cacheline */
+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
+ uint32_t *cacheline, uint32_t val)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
+/* Small-width signed values (two's-complement) will decode into medium-width
+ * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
+ * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
+ * 249. Likewise -120 would decode as 136.) This function allows the caller to
+ * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
+ * encoding, will become 0xfffffff9 if you cast the return value to uint32_t).
+ */
+static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
+ uint32_t val)
+{
+ QBMAN_BUG_ON(val >= (1u << code->width));
+ /* code->width should never exceed the width of val. If it does then a
+ * different function with larger val size must be used to translate
+ * from unsigned to signed
+ */
+ QBMAN_BUG_ON(code->width > sizeof(val) * CHAR_BIT);
+ /* If the high bit was set, it was encoding a negative */
+ if (val >= 1u << (code->width - 1))
+ return (int32_t)0 - (int32_t)(((uint32_t)1 << code->width) -
+ val);
+ /* Otherwise, it was encoding a positive */
+ return (int32_t)val;
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * a "descriptor" type that the caller can instantiate however they like.
+ * Ultimately though, it is just a cacheline of binary storage (or something
+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
+ * holding pre-formatted pieces of hardware commands. The performance-critical
+ * code can then copy these descriptors directly into hardware command
+ * registers more efficiently than trying to construct/format commands
+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/common/dpaa2/qbman/qbman_private.h b/drivers/common/dpaa2/qbman/qbman_private.h
new file mode 100644
index 0000000..24fea62
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_private.h
@@ -0,0 +1,167 @@
+/* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+/* Perform extra checking */
+#define QBMAN_CHECKING
+
+/* To maximise the amount of logic that is common between the Linux driver and
+ * other targets (such as the embedded MC firmware), we pivot here between the
+ * inclusion of two platform-specific headers.
+ *
+ * The first, qbman_sys_decl.h, includes any and all required system headers as
+ * well as providing any definitions for the purposes of compatibility. The
+ * second, qbman_sys.h, is where platform-specific routines go.
+ *
+ * The point of the split is that the platform-independent code (including this
+ * header) may depend on platform-specific declarations, yet other
+ * platform-specific routines may depend on platform-independent definitions.
+ */
+
+#include "qbman_sys_decl.h"
+
+/* When things go wrong, it is a convenient trick to insert a few FOO()
+ * statements in the code to trace progress. TODO: remove this once we are
+ * hacking the code less actively.
+ */
+#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+do { \
+ if (!(loopvar--)) \
+ QBMAN_BUG_ON(NULL == "DBG_POLL_CHECK"); \
+} while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ pr_info("%s", buf);
+ }
+}
+
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#include "qbman_sys.h"
diff --git a/drivers/common/dpaa2/qbman/qbman_sys.h b/drivers/common/dpaa2/qbman/qbman_sys.h
new file mode 100644
index 0000000..5d801c0
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys.h
@@ -0,0 +1,382 @@
+/* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required.
+ */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness.
+ */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+
+static inline uint32_t make_le24(uint32_t val)
+{
+ return (((val & 0xff) << 16) | (val & 0xff00) |
+ ((val & 0xff0000) >> 16));
+}
+
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+#else
+#define make_le32(val) (val)
+#define make_le24(val) (val)
+#define make_le32_n(val, len) do {} while (0)
+#endif
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder.
+ */
+ uint8_t *cena;
+ uint8_t __iomem *addr_cena;
+ uint8_t __iomem *addr_cinh;
+ uint32_t idx;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void *qbman_cena_write_start_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 1; loop--)
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+ lwsync();
+ __raw_writel(shadow[0], s->addr_cena + offset);
+ dcbf(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+ hexdump(cmd, 64);
+#endif
+ dcbf(s->addr_cena + offset);
+}
+
+static inline uint32_t qbman_cena_read_reg(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ return __raw_readl(s->addr_cena + offset);
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = (uint32_t *)(s->cena + offset);
+ unsigned int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void *qbman_cena_read_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return s->addr_cena + offset;
+}
+
+static inline void qbman_cena_invalidate(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here.
+ */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x2)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x2)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- TRUE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- TRUE)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- TRUE)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- TRUE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) |
+ e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d,
+ uint8_t dqrr_size)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->idx = (uint32_t)d->idx;
+ s->cena = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!s->cena) {
+ pr_err("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+ s->eqcr_mode = d->eqcr_mode;
+ QBMAN_BUG_ON(d->idx < 0);
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ QBMAN_BUG_ON(reg);
+#endif
+ if (s->eqcr_mode == qman_eqcr_vb_array)
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 1, 1, 1, 1,
+ 1, 1);
+ else
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 2, 3, 2, 2, 1, 1, 1, 1,
+ 1, 1);
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ pr_err("The portal %d is not enabled!\n", s->idx);
+ kfree(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free_page((unsigned long)s->cena);
+}
+
+static inline void *
+qbman_cena_write_start_wo_shadow_fast(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_sys_decl.h b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
new file mode 100644
index 0000000..c49da57
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 <compat.h>
+#include <fsl_qbman_base.h>
+
+/* Sanity check */
+#if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && \
+ (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
+#error "Unknown endianness!"
+#endif
+
+/* The platform-independent code shouldn't need endianness, except for
+ * weird/fast-path cases like qbman_result_has_token(), which needs to
+ * perform a passive and endianness-specific test on a read-only data structure
+ * very quickly. It's an exception, and this symbol is used for that case.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define DQRR_TOK_OFFSET 0
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 24
+#define SCN_STATE_OFFSET_IN_MEM 8
+#define SCN_RID_OFFSET_IN_MEM 8
+#else
+#define DQRR_TOK_OFFSET 24
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 0
+#define SCN_STATE_OFFSET_IN_MEM 16
+#define SCN_RID_OFFSET_IN_MEM 0
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
+#define lwsync() { asm volatile("dmb st" : : : "memory"); }
+#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); }
+#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); }
+static inline void prefetch_for_load(void *p)
+{
+ asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p));
+}
+
+static inline void prefetch_for_store(void *p)
+{
+ asm volatile("prfm pstl1keep, [%0, #64]" : : "r" (p));
+}
diff --git a/drivers/common/dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map
new file mode 100644
index 0000000..f653421
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map
@@ -0,0 +1,27 @@
+DPDK_17.02 {
+ global:
+
+ qbman_check_command_complete;
+ qbman_eq_desc_clear;
+ qbman_eq_desc_set_fq;
+ qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_qd;
+ qbman_eq_desc_set_response;
+ qbman_get_version;
+ qbman_pull_desc_clear;
+ qbman_pull_desc_set_fq;
+ qbman_pull_desc_set_numframes;
+ qbman_pull_desc_set_storage;
+ qbman_release_desc_clear;
+ qbman_release_desc_set_bpid;
+ qbman_result_DQ_fd;
+ qbman_result_DQ_flags;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
+ qbman_swp_init;
+ qbman_swp_pull;
+ qbman_swp_release;
+ qbman_swp_send_multiple;
+
+ local: *;
+};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-01-19 19:07 ` Ferruh Yigit
2017-01-20 4:48 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-19 19:07 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Geoff Thorpe, Roy Pledge
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> QBMAN, is a hardware block which interfaces with the other
> accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
> SoC for queue, buffer and packet scheduling.
>
> This patch introduces a userspace driver for interfacing with
> the QBMAN hw block.
>
> The qbman-portal component provides APIs to do the low level
> hardware bit twiddling for operations such as:
> -initializing Qman software portals
> -building and sending portal commands
> -portal interrupt configuration and processing
>
> This same/similar code is used in kernel and compat file is used
> to make it working in user space.
>
> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
> Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> diff --git a/drivers/common/dpaa2/qbman/include/compat.h b/drivers/common/dpaa2/qbman/include/compat.h
> new file mode 100644
> index 0000000..d321cc6
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/include/compat.h
> @@ -0,0 +1,403 @@
> +/* Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
> + * All rights reserved.
Should this say "# BSD LICENSE" ? As in other file comments..
There are multiple this kind of usage.
> + *
> + * 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 nor the
> + * names of its contributors may be used to endorse or promote products
> + * derived from this software without specific prior written permission.
> + *
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver
2017-01-19 19:07 ` Ferruh Yigit
@ 2017-01-20 4:48 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 4:48 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Geoff Thorpe, Roy Pledge
On 1/20/2017 12:37 AM, Ferruh Yigit wrote:
> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>> QBMAN, is a hardware block which interfaces with the other
>> accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
>> SoC for queue, buffer and packet scheduling.
>>
>> This patch introduces a userspace driver for interfacing with
>> the QBMAN hw block.
>>
>> The qbman-portal component provides APIs to do the low level
>> hardware bit twiddling for operations such as:
>> -initializing Qman software portals
>> -building and sending portal commands
>> -portal interrupt configuration and processing
>>
>> This same/similar code is used in kernel and compat file is used
>> to make it working in user space.
>>
>> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
>> Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>
> <...>
>
>> diff --git a/drivers/common/dpaa2/qbman/include/compat.h b/drivers/common/dpaa2/qbman/include/compat.h
>> new file mode 100644
>> index 0000000..d321cc6
>> --- /dev/null
>> +++ b/drivers/common/dpaa2/qbman/include/compat.h
>> @@ -0,0 +1,403 @@
>> +/* Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
>> + * All rights reserved.
>
> Should this say "# BSD LICENSE" ? As in other file comments..
> There are multiple this kind of usage.
>
I can add it as per convention followed in DPDK.
We are generally not adding that as BSD LICENSE is self determined by
the clauses.
>> + *
>> + * 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 nor the
>> + * names of its contributors may be used to endorse or promote products
>> + * derived from this software without specific prior written permission.
>> + *
>
> <...>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (4 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 03/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 17:12 ` Thomas Monjalon
2017-01-19 19:08 ` Ferruh Yigit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions Hemant Agrawal
` (29 subsequent siblings)
35 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
for NXP DPAA2 SoCs.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 6 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/Makefile | 1 +
drivers/bus/Makefile | 36 ++++++
drivers/bus/fslmc/Makefile | 52 +++++++++
drivers/bus/fslmc/fslmc_bus.c | 125 +++++++++++++++++++++
drivers/bus/fslmc/rte_fslmc.h | 148 +++++++++++++++++++++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 7 ++
8 files changed, 380 insertions(+)
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
create mode 100644 drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
diff --git a/config/common_base b/config/common_base
index a64fd8b..e6b4d60 100644
--- a/config/common_base
+++ b/config/common_base
@@ -291,6 +291,12 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_COMMON=n
+
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=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 c57c340..800e22b 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -46,3 +46,8 @@ CONFIG_RTE_MAX_NUMA_NODES=1
# Compile Support Libraries for DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
+
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=y
diff --git a/drivers/Makefile b/drivers/Makefile
index d5580f6..bdae63b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -32,6 +32,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
+DIRS-y += bus
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000..60e9764
--- /dev/null
+++ b/drivers/bus/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_FSLMC_BUS) += fslmc
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
new file mode 100644
index 0000000..c4f22ed
--- /dev/null
+++ b/drivers/bus/fslmc/Makefile
@@ -0,0 +1,52 @@
+# 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_fslmcbus.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_pmd_fslmcbus_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
new file mode 100644
index 0000000..8a4f519
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -0,0 +1,125 @@
+/*-
+ * 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.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_ethdev.h>
+
+#include "rte_fslmc.h"
+
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+ RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+struct rte_fslmc_bus rte_fslmc_bus;
+
+static int
+rte_fslmc_scan(void)
+{
+ return 0;
+}
+
+static int
+rte_fslmc_match(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
+ return 0;
+
+ return 1;
+}
+
+static int
+rte_fslmc_probe(void)
+{
+ int ret = -1;
+ struct rte_dpaa2_device *dev;
+ struct rte_dpaa2_driver *drv;
+
+ TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
+ TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
+ ret = rte_fslmc_match(drv, dev);
+ if (ret)
+ continue;
+
+ if (!drv->probe)
+ continue;
+
+ ret = drv->probe(drv, dev);
+ if (ret)
+ FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
+ break;
+ }
+ }
+ return ret;
+}
+
+/*register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
+{
+ RTE_VERIFY(driver);
+
+ TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = &rte_fslmc_bus;
+}
+
+/*un-register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver)
+{
+ struct rte_fslmc_bus *fslmc_bus;
+
+ fslmc_bus = driver->fslmc_bus;
+
+ TAILQ_REMOVE(&fslmc_bus->driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = NULL;
+}
+
+struct rte_fslmc_bus rte_fslmc_bus = {
+ .bus = {
+ .scan = rte_fslmc_scan,
+ .probe = rte_fslmc_probe,
+ },
+ .device_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.device_list),
+ .driver_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus);
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
new file mode 100644
index 0000000..040ab95
--- /dev/null
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -0,0 +1,148 @@
+/*-
+ * 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 _RTE_FSLMC_H_
+#define _RTE_FSLMC_H_
+
+/**
+ * @file
+ *
+ * RTE FSLMC Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/** Name of FSLMC Bus */
+#define FSLMC_BUS_NAME "FSLMC"
+
+struct rte_dpaa2_driver;
+
+/* DPAA2 Device and Driver lists for FSLMC bus */
+TAILQ_HEAD(rte_fslmc_device_list, rte_dpaa2_device);
+TAILQ_HEAD(rte_fslmc_driver_list, rte_dpaa2_driver);
+
+extern struct rte_fslmc_bus rte_fslmc_bus;
+
+/**
+ * A structure describing a DPAA2 device.
+ */
+struct rte_dpaa2_device {
+ TAILQ_ENTRY(rte_dpaa2_device) next; /**< Next probed DPAA2 device. */
+ struct rte_device device; /**< Inherit core device */
+ union {
+ struct rte_eth_dev *eth_dev; /**< ethernet device */
+ struct rte_cryptodev *cryptodev; /**< Crypto Device */
+ };
+ uint16_t dev_type; /**< Device Type */
+ uint16_t object_id; /**< DPAA2 Object ID */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
+ struct rte_dpaa2_driver *driver; /**< Associated driver */
+};
+
+typedef int (*rte_dpaa2_probe_t)(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev);
+typedef int (*rte_dpaa2_remove_t)(struct rte_dpaa2_device *dpaa2_dev);
+
+/**
+ * A structure describing a DPAA2 driver.
+ */
+struct rte_dpaa2_driver {
+ TAILQ_ENTRY(rte_dpaa2_driver) next; /**< Next in list. */
+ struct rte_driver driver; /**< Inherit core driver. */
+ struct rte_fslmc_bus *fslmc_bus; /**< FSLMC bus reference */
+ uint32_t drv_flags; /**< Flags for controlling device.*/
+ uint16_t drv_type; /**< Driver Type */
+ rte_dpaa2_probe_t probe;
+ rte_dpaa2_remove_t remove;
+};
+
+/*
+ * FSLMC bus
+ */
+struct rte_fslmc_bus {
+ struct rte_bus bus; /**< Generic Bus object */
+ struct rte_fslmc_device_list device_list;
+ /**< FSLMC DPAA2 Device list */
+ struct rte_fslmc_driver_list driver_list;
+ /**< FSLMC DPAA2 Driver list */
+ int device_count;
+ /**< Optional: Count of devices on bus */
+};
+
+/**
+ * Register a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be registered.
+ */
+void rte_fslmc_driver_register(struct rte_dpaa2_driver *driver);
+
+/**
+ * Unregister a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be unregistered.
+ */
+void rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver);
+
+/** Helper for DPAA2 device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_DPAA2(nm, dpaa2_drv) \
+RTE_INIT(dpaa2initfn_ ##nm); \
+static void dpaa2initfn_ ##nm(void) \
+{\
+ (dpaa2_drv).driver.name = RTE_STR(nm);\
+ rte_fslmc_driver_register(&dpaa2_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_FSLMC_H_ */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
new file mode 100644
index 0000000..4d525ba
--- /dev/null
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -0,0 +1,7 @@
+DPDK_17.02 {
+ global:
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+
+ local: *;
+};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
@ 2017-01-19 17:12 ` Thomas Monjalon
2017-01-19 19:08 ` Ferruh Yigit
1 sibling, 0 replies; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-19 17:12 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
2017-01-19 18:53, Hemant Agrawal:
> The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
> for NXP DPAA2 SoCs.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> config/common_base | 6 +
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
> drivers/Makefile | 1 +
> drivers/bus/Makefile | 36 ++++++
> drivers/bus/fslmc/Makefile | 52 +++++++++
> drivers/bus/fslmc/fslmc_bus.c | 125 +++++++++++++++++++++
> drivers/bus/fslmc/rte_fslmc.h | 148 +++++++++++++++++++++++++
> drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 7 ++
Good to see a first bus driver.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
2017-01-19 17:12 ` Thomas Monjalon
@ 2017-01-19 19:08 ` Ferruh Yigit
2017-01-20 5:05 ` Shreyansh Jain
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-19 19:08 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
> for NXP DPAA2 SoCs.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> +#
> +# library name
> +#
> +LIB = librte_pmd_fslmcbus.a
Since now there is a bus folder/driver, what do you think nameming
library with librte_bus_ prefix, like: librte_bus_fslmc.a
<...>
> +
> +static int
> +rte_fslmc_probe(void)
> +{
> + int ret = -1;
If any bus->probe() fails, rte_bus_probe() breaks and returns error,
which cause app to exit.
Here if there is no device or driver in the bus, function is returning
error, I guess it should be returning zero for this case.
> + struct rte_dpaa2_device *dev;
> + struct rte_dpaa2_driver *drv;
> +
> + TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
> + TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
> + ret = rte_fslmc_match(drv, dev);
> + if (ret)
> + continue;
> +
> + if (!drv->probe)
> + continue;
> +
> + ret = drv->probe(drv, dev);
> + if (ret)
> + FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
> + break;
> + }
> + }
> + return ret;
> +}
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-19 19:08 ` Ferruh Yigit
@ 2017-01-20 5:05 ` Shreyansh Jain
2017-01-20 11:39 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-20 5:05 UTC (permalink / raw)
To: Ferruh Yigit, Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob
On Friday 20 January 2017 12:38 AM, Ferruh Yigit wrote:
> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>> The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
>> for NXP DPAA2 SoCs.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>
> <...>
>
>> +#
>> +# library name
>> +#
>> +LIB = librte_pmd_fslmcbus.a
>
> Since now there is a bus folder/driver, what do you think nameming
> library with librte_bus_ prefix, like: librte_bus_fslmc.a
>
> <...>
>
>> +
>> +static int
>> +rte_fslmc_probe(void)
>> +{
>> + int ret = -1;
>
> If any bus->probe() fails, rte_bus_probe() breaks and returns error,
> which cause app to exit.
> Here if there is no device or driver in the bus, function is returning
> error, I guess it should be returning zero for this case.
It is a nice point of discussion (even in the bus patch). Should Bus
iteration for scan/probe fail if any bus implementation fails?
In the initial series I had placed a 'TODO' in the bus patch to get some
comments - I couldn't make a decision so the final bus scan/probe loop
'fails if any bus fails whether in scan or probe'.
I think that EAL should continue looping over buses irrespective of bus
failure - specially removing such dependencies on bus implementations to
return a valid code compatible with EAL's design.
>
>> + struct rte_dpaa2_device *dev;
>> + struct rte_dpaa2_driver *drv;
>> +
>> + TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
>> + TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
>> + ret = rte_fslmc_match(drv, dev);
>> + if (ret)
>> + continue;
>> +
>> + if (!drv->probe)
>> + continue;
>> +
>> + ret = drv->probe(drv, dev);
>> + if (ret)
>> + FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
>> + break;
>> + }
>> + }
>> + return ret;
>> +}
>
> <...>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-20 5:05 ` Shreyansh Jain
@ 2017-01-20 11:39 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-20 11:39 UTC (permalink / raw)
To: Shreyansh Jain, Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob
On 1/20/2017 5:05 AM, Shreyansh Jain wrote:
> On Friday 20 January 2017 12:38 AM, Ferruh Yigit wrote:
>> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>>> The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
>>> for NXP DPAA2 SoCs.
>>>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> ---
>>
>> <...>
>>
>>> +#
>>> +# library name
>>> +#
>>> +LIB = librte_pmd_fslmcbus.a
>>
>> Since now there is a bus folder/driver, what do you think nameming
>> library with librte_bus_ prefix, like: librte_bus_fslmc.a
>>
>> <...>
>>
>>> +
>>> +static int
>>> +rte_fslmc_probe(void)
>>> +{
>>> + int ret = -1;
>>
>> If any bus->probe() fails, rte_bus_probe() breaks and returns error,
>> which cause app to exit.
>> Here if there is no device or driver in the bus, function is returning
>> error, I guess it should be returning zero for this case.
>
> It is a nice point of discussion (even in the bus patch). Should Bus
> iteration for scan/probe fail if any bus implementation fails?
>
> In the initial series I had placed a 'TODO' in the bus patch to get some
> comments - I couldn't make a decision so the final bus scan/probe loop
> 'fails if any bus fails whether in scan or probe'.
>
> I think that EAL should continue looping over buses irrespective of bus
> failure - specially removing such dependencies on bus implementations to
> return a valid code compatible with EAL's design.
Agree to fix this in eal.
>
>>
>>> + struct rte_dpaa2_device *dev;
>>> + struct rte_dpaa2_driver *drv;
>>> +
>>> + TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
>>> + TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
>>> + ret = rte_fslmc_match(drv, dev);
>>> + if (ret)
>>> + continue;
>>> +
>>> + if (!drv->probe)
>>> + continue;
>>> +
>>> + ret = drv->probe(drv, dev);
>>> + if (ret)
>>> + FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
>>> + break;
>>> + }
>>> + }
>>> + return ret;
>>> +}
>>
>> <...>
>>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (5 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 04/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 19:10 ` Ferruh Yigit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support Hemant Agrawal
` (28 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Cristian Sovaiala, Hemant Agrawal
This patch intoduces the DPAA2 MC(Management complex Driver).
This is a minimal set of low level functions to send and
receive commands to the fsl-mc. It includes support for basic
management commands and commands to manipulate MC objects.
This is common to be used by various DPAA2 PMDs. e.g.net, crypto
and other drivers.
This is a low level library also used in kernel.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 7 ++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 231 ++++++++++++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 98 ++++++++++++++++
drivers/bus/fslmc/mc/mc_sys.c | 107 ++++++++++++++++++
4 files changed, 443 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index c4f22ed..21e9f17 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -37,6 +37,10 @@ LIB = librte_pmd_fslmcbus.a
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += "-Wno-strict-aliasing"
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
# versioning export map
EXPORT_MAP := rte_pmd_fslmcbus_version.map
@@ -44,6 +48,9 @@ EXPORT_MAP := rte_pmd_fslmcbus_version.map
# library version
LIBABIVER := 1
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/mc_sys.c
+
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
new file mode 100644
index 0000000..cbd3995
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
@@ -0,0 +1,231 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#define MC_CMD_NUM_OF_PARAMS 7
+
+#define MAKE_UMASK64(_width) \
+ ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : \
+ (uint64_t)-1))
+
+static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val)
+{
+ return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+
+static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width)
+{
+ return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+struct mc_command {
+ uint64_t header;
+ uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+/**
+ * enum mc_cmd_status - indicates MC status at command response
+ * @MC_CMD_STATUS_OK: Completed successfully
+ * @MC_CMD_STATUS_READY: Ready to be processed
+ * @MC_CMD_STATUS_AUTH_ERR: Authentication error
+ * @MC_CMD_STATUS_NO_PRIVILEGE: No privilege
+ * @MC_CMD_STATUS_DMA_ERR: DMA or I/O error
+ * @MC_CMD_STATUS_CONFIG_ERR: Configuration error
+ * @MC_CMD_STATUS_TIMEOUT: Operation timed out
+ * @MC_CMD_STATUS_NO_RESOURCE: No resources
+ * @MC_CMD_STATUS_NO_MEMORY: No memory available
+ * @MC_CMD_STATUS_BUSY: Device is busy
+ * @MC_CMD_STATUS_UNSUPPORTED_OP: Unsupported operation
+ * @MC_CMD_STATUS_INVALID_STATE: Invalid state
+ */
+enum mc_cmd_status {
+ MC_CMD_STATUS_OK = 0x0,
+ MC_CMD_STATUS_READY = 0x1,
+ MC_CMD_STATUS_AUTH_ERR = 0x3,
+ MC_CMD_STATUS_NO_PRIVILEGE = 0x4,
+ MC_CMD_STATUS_DMA_ERR = 0x5,
+ MC_CMD_STATUS_CONFIG_ERR = 0x6,
+ MC_CMD_STATUS_TIMEOUT = 0x7,
+ MC_CMD_STATUS_NO_RESOURCE = 0x8,
+ MC_CMD_STATUS_NO_MEMORY = 0x9,
+ MC_CMD_STATUS_BUSY = 0xA,
+ MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,
+ MC_CMD_STATUS_INVALID_STATE = 0xC
+};
+
+/* MC command flags */
+
+/**
+ * High priority flag
+ */
+#define MC_CMD_FLAG_PRI 0x00008000
+/**
+ * Command completion flag
+ */
+#define MC_CMD_FLAG_INTR_DIS 0x01000000
+
+/**
+ * Command ID field offset
+ */
+#define MC_CMD_HDR_CMDID_O 48
+/**
+ * Command ID field size
+ */
+#define MC_CMD_HDR_CMDID_S 16
+/**
+ * Token field offset
+ */
+#define MC_CMD_HDR_TOKEN_O 32
+/**
+ * Token field size
+ */
+#define MC_CMD_HDR_TOKEN_S 16
+/**
+ * Status field offset
+ */
+#define MC_CMD_HDR_STATUS_O 16
+/**
+ * Status field size
+ */
+#define MC_CMD_HDR_STATUS_S 8
+/**
+ * Flags field offset
+ */
+#define MC_CMD_HDR_FLAGS_O 0
+/**
+ * Flags field size
+ */
+#define MC_CMD_HDR_FLAGS_S 32
+/**
+ * Command flags mask
+ */
+#define MC_CMD_HDR_FLAGS_MASK 0xFF00FF00
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+ ((enum mc_cmd_status)mc_dec((_hdr), \
+ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
+
+#define MC_PREP_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= cpu_to_le64(mc_enc((_offset), (_width), _arg)))
+
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(cpu_to_le64(_ext[_param]), (_offset), (_width)))
+
+#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg))
+
+#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width)))
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ uint64_t hdr;
+
+ hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+ hdr |= mc_enc(MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S,
+ (cmd_flags & MC_CMD_HDR_FLAGS_MASK));
+ hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
+ hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+ MC_CMD_STATUS_READY);
+
+ return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+ struct mc_command *cmd)
+{
+ int i;
+ uint32_t word;
+
+ /* copy command parameters into the portal */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ iowrite64(cmd->params[i], &portal->params[i]);
+
+ /* submit the command by writing the header */
+ word = (uint32_t)mc_dec(cmd->header, 32, 32);
+ iowrite32(word, (((uint32_t *)&portal->header) + 1));
+
+ word = (uint32_t)mc_dec(cmd->header, 0, 32);
+ iowrite32(word, (uint32_t *)&portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(
+ struct mc_command __iomem *portal,
+ struct mc_command *resp)
+{
+ int i;
+ enum mc_cmd_status status;
+
+ /* Copy command response header from MC portal: */
+ resp->header = ioread64(&portal->header);
+ status = MC_CMD_HDR_READ_STATUS(resp->header);
+ if (status != MC_CMD_STATUS_OK)
+ return status;
+
+ /* Copy command response data from MC portal: */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ resp->params[i] = ioread64(&portal->params[i]);
+
+ return status;
+}
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_mc_sys.h b/drivers/bus/fslmc/mc/fsl_mc_sys.h
new file mode 100644
index 0000000..d9d43e5
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_sys.h
@@ -0,0 +1,98 @@
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#ifdef __linux_driver__
+
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/slab.h>
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+
+#else /* __linux_driver__ */
+
+#include <stdio.h>
+#include <libio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <linux/byteorder/little_endian.h>
+
+#define cpu_to_le64(x) __cpu_to_le64(x)
+#ifndef dmb
+#define dmb() {__asm__ __volatile__("" : : : "memory"); }
+#endif
+#define __iormb() dmb()
+#define __iowmb() dmb()
+#define __arch_getq(a) (*(volatile unsigned long *)(a))
+#define __arch_putq(v, a) (*(volatile unsigned long *)(a) = (v))
+#define __arch_putq32(v, a) (*(volatile unsigned int *)(a) = (v))
+#define readq(c) \
+ ({ uint64_t __v = __arch_getq(c); __iormb(); __v; })
+#define writeq(v, c) \
+ ({ uint64_t __v = v; __iowmb(); __arch_putq(__v, c); __v; })
+#define writeq32(v, c) \
+ ({ uint32_t __v = v; __iowmb(); __arch_putq32(__v, c); __v; })
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+#define iowrite32(_v, _p) writeq32(_v, _p)
+#define __iomem
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+/*GPP is supposed to use MC commands with low priority*/
+#define CMD_PRI_LOW 0 /*!< Low Priority command indication */
+
+struct mc_command;
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* __linux_driver__ */
+
+#endif /* _FSL_MC_SYS_H */
diff --git a/drivers/bus/fslmc/mc/mc_sys.c b/drivers/bus/fslmc/mc/mc_sys.c
new file mode 100644
index 0000000..c428624
--- /dev/null
+++ b/drivers/bus/fslmc/mc/mc_sys.c
@@ -0,0 +1,107 @@
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+
+#include <rte_spinlock.h>
+
+/** User space framework uses MC Portal in shared mode. Following change
+ * introduces lock in MC FLIB
+ */
+
+/**
+ * A static spinlock initializer.
+ */
+static rte_spinlock_t mc_portal_lock = RTE_SPINLOCK_INITIALIZER;
+
+static int mc_status_to_error(enum mc_cmd_status status)
+{
+ switch (status) {
+ case MC_CMD_STATUS_OK:
+ return 0;
+ case MC_CMD_STATUS_AUTH_ERR:
+ return -EACCES; /* Token error */
+ case MC_CMD_STATUS_NO_PRIVILEGE:
+ return -EPERM; /* Permission denied */
+ case MC_CMD_STATUS_DMA_ERR:
+ return -EIO; /* Input/Output error */
+ case MC_CMD_STATUS_CONFIG_ERR:
+ return -EINVAL; /* Device not configured */
+ case MC_CMD_STATUS_TIMEOUT:
+ return -ETIMEDOUT; /* Operation timed out */
+ case MC_CMD_STATUS_NO_RESOURCE:
+ return -ENAVAIL; /* Resource temporarily unavailable */
+ case MC_CMD_STATUS_NO_MEMORY:
+ return -ENOMEM; /* Cannot allocate memory */
+ case MC_CMD_STATUS_BUSY:
+ return -EBUSY; /* Device busy */
+ case MC_CMD_STATUS_UNSUPPORTED_OP:
+ return -ENOTSUP; /* Operation not supported by device */
+ case MC_CMD_STATUS_INVALID_STATE:
+ return -ENODEV; /* Invalid device state */
+ default:
+ break;
+ }
+
+ /* Not expected to reach here */
+ return -EINVAL;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+ enum mc_cmd_status status;
+
+ if (!mc_io || !mc_io->regs)
+ return -EACCES;
+
+ /* --- Call lock function here in case portal is shared --- */
+ rte_spinlock_lock(&mc_portal_lock);
+
+ mc_write_command(mc_io->regs, cmd);
+
+ /* Spin until status changes */
+ do {
+ status = MC_CMD_HDR_READ_STATUS(ioread64(mc_io->regs));
+
+ /* --- Call wait function here to prevent blocking ---
+ * Change the loop condition accordingly to exit on timeout.
+ */
+ } while (status == MC_CMD_STATUS_READY);
+
+ /* Read the response back into the command buffer */
+ mc_read_response(mc_io->regs, cmd);
+
+ /* --- Call unlock function here in case portal is shared --- */
+ rte_spinlock_unlock(&mc_portal_lock);
+
+ return mc_status_to_error(status);
+}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions Hemant Agrawal
@ 2017-01-19 19:10 ` Ferruh Yigit
2017-01-20 4:52 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-19 19:10 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Cristian Sovaiala
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> This patch intoduces the DPAA2 MC(Management complex Driver).
>
> This is a minimal set of low level functions to send and
> receive commands to the fsl-mc. It includes support for basic
> management commands and commands to manipulate MC objects.
>
> This is common to be used by various DPAA2 PMDs. e.g.net, crypto
> and other drivers.
>
> This is a low level library also used in kernel.
>
> Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
<...>
> diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
> new file mode 100644
> index 0000000..cbd3995
> --- /dev/null
> +++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
> @@ -0,0 +1,231 @@
> +/* Copyright 2013-2016 Freescale Semiconductor Inc.
> + * Copyright (c) 2016 NXP.
> + *
> + * 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 the above-listed copyright holders nor the
> + * names of any contributors may be used to endorse or promote products
> + * derived from this software without specific prior written permission.
> + *
> + *
> + * ALTERNATIVELY, this software may be distributed under the terms of the
> + * GNU General Public License ("GPL") as published by the Free Software
> + * Foundation, either version 2 of that License or (at your option) any
> + * later version.
Dual licensed, GPL and BSD ?
> + *
> + * 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 HOLDERS 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.
> + */
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions
2017-01-19 19:10 ` Ferruh Yigit
@ 2017-01-20 4:52 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 4:52 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Cristian Sovaiala
On 1/20/2017 12:40 AM, Ferruh Yigit wrote:
> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>> This patch intoduces the DPAA2 MC(Management complex Driver).
>>
>> This is a minimal set of low level functions to send and
>> receive commands to the fsl-mc. It includes support for basic
>> management commands and commands to manipulate MC objects.
>>
>> This is common to be used by various DPAA2 PMDs. e.g.net, crypto
>> and other drivers.
>>
>> This is a low level library also used in kernel.
>>
>> Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> <...>
>
>> diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
>> new file mode 100644
>> index 0000000..cbd3995
>> --- /dev/null
>> +++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
>> @@ -0,0 +1,231 @@
>> +/* Copyright 2013-2016 Freescale Semiconductor Inc.
>> + * Copyright (c) 2016 NXP.
>> + *
>> + * 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 the above-listed copyright holders nor the
>> + * names of any contributors may be used to endorse or promote products
>> + * derived from this software without specific prior written permission.
>> + *
>> + *
>> + * ALTERNATIVELY, this software may be distributed under the terms of the
>> + * GNU General Public License ("GPL") as published by the Free Software
>> + * Foundation, either version 2 of that License or (at your option) any
>> + * later version.
>
> Dual licensed, GPL and BSD ?
>
This is new code. We are submitting same file to Uboot/UEFI and kernel.
That is the reason, we added dual license.
In Userspace - only BSD license is applicable?
Is that a issue?
>> + *
>> + * 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 HOLDERS 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.
>> + */
> <...>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (6 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 05/33] bus/fslmc: introduce mc object functions Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 17:14 ` Thomas Monjalon
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 07/33] bus/fslmc: add mc dpio " Hemant Agrawal
` (27 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
This patch add support for dpni object support in MC
driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpni.c | 732 ++++++++++++++
drivers/bus/fslmc/mc/fsl_dpkg.h | 177 ++++
drivers/bus/fslmc/mc/fsl_dpni.h | 1210 ++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 327 +++++++
drivers/bus/fslmc/mc/fsl_net.h | 480 ++++++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 22 +
7 files changed, 2949 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 21e9f17..c3616e6 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -49,6 +49,7 @@ EXPORT_MAP := rte_pmd_fslmcbus_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/dpni.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpni.c b/drivers/bus/fslmc/mc/dpni.c
new file mode 100644
index 0000000..1e1415f
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpni.c
@@ -0,0 +1,732 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpkg.h b/drivers/bus/fslmc/mc/fsl_dpkg.h
new file mode 100644
index 0000000..8cabaaf
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpkg.h
@@ -0,0 +1,177 @@
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni.h b/drivers/bus/fslmc/mc/fsl_dpni.h
new file mode 100644
index 0000000..6a8c783
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni.h
@@ -0,0 +1,1210 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni_cmd.h b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..330334c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
@@ -0,0 +1,327 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_net.h b/drivers/bus/fslmc/mc/fsl_net.h
new file mode 100644
index 0000000..cf5431b
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_net.h
@@ -0,0 +1,480 @@
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 4d525ba..d49dda8 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -1,5 +1,27 @@
DPDK_17.02 {
global:
+ dpni_close;
+ dpni_disable;
+ dpni_enable;
+ dpni_get_attributes;
+ dpni_get_link_state;
+ dpni_get_primary_mac_addr;
+ dpni_get_qdid;
+ dpni_get_queue;
+ dpni_get_statistics;
+ dpni_open;
+ dpni_prepare_key_cfg;
+ dpni_reset;
+ dpni_reset_statistics;
+ dpni_set_buffer_layout;
+ dpni_set_errors_behavior;
+ dpni_set_max_frame_length;
+ dpni_set_offload;
+ dpni_set_pools;
+ dpni_set_queue;
+ dpni_set_rx_tc_dist;
+ dpni_set_tx_confirmation_mode;
+ dpni_set_unicast_promisc;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support Hemant Agrawal
@ 2017-01-19 17:14 ` Thomas Monjalon
2017-01-20 12:00 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-19 17:14 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean
2017-01-19 18:53, Hemant Agrawal:
> This patch add support for dpni object support in MC
> driver.
>
> DPNI represent a network interface object in DPAA2.
I really think you need to provide a design doc for this bus,
event if it a collection of links to some web resources.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support
2017-01-19 17:14 ` Thomas Monjalon
@ 2017-01-20 12:00 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 12:00 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean
On 1/19/2017 10:44 PM, Thomas Monjalon wrote:
> 2017-01-19 18:53, Hemant Agrawal:
>> This patch add support for dpni object support in MC
>> driver.
>>
>> DPNI represent a network interface object in DPAA2.
>
> I really think you need to provide a design doc for this bus,
> event if it a collection of links to some web resources.
>
I thought we covered it decently in the doc.
Please see if the following link helps. it is a good introduction for
the Management Complex bus on DPAA2.
https://community.nxp.com/servlet/JiveServlet/downloadBody/330322-102-1-263940/EUF-NET-T1751%20Logical_Abstraction_and_Resource_Management_with_Layerscape_Management_Complex%20%28N%20Erez%29.pdf
or at,
https://community.nxp.com/docs/DOC-330322
Let me know if you have any access issue.
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 07/33] bus/fslmc: add mc dpio object support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (7 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 06/33] bus/fslmc: add mc dpni object support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 08/33] bus/fslmc: add mc dpbp " Hemant Agrawal
` (26 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
This patch adds the DPIO object support in MC driver.
DPIO - Data Path Input Output represent the processing
context to access the QBMAN HW for packet I/O.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpio.c | 272 ++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio.h | 275 +++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 114 ++++++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 8 +
5 files changed, 670 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index c3616e6..fa1ce13 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpio.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpio.c b/drivers/bus/fslmc/mc/dpio.c
new file mode 100644
index 0000000..35a06d6
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpio.c
@@ -0,0 +1,272 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpio.h>
+#include <fsl_dpio_cmd.h>
+
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPIO_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
+ cmd_flags,
+ token);
+ DPIO_CMD_SET_STASHING_DEST(cmd, sdest);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_STASHING_DEST,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_STASHING_DEST(cmd, *sdest);
+
+ return 0;
+}
+
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPIO_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpio.h b/drivers/bus/fslmc/mc/fsl_dpio.h
new file mode 100644
index 0000000..8cb4b99
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio.h
@@ -0,0 +1,275 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPIO_H
+#define __FSL_DPIO_H
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and any MC portals
+ * assigned to the parent container; this token must be used in
+ * all subsequent commands for this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token);
+
+/**
+ * dpio_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * struct dpio_cfg - Structure representing DPIO configuration
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_cfg {
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_create() - Create the DPIO object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPIO object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpio_destroy() - Destroy the DPIO object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_is_enabled() - Check if the DPIO is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_set_stashing_destination() - Set the stashing destination.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest);
+
+/**
+ * dpio_get_stashing_destination() - Get the stashing destination..
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: Returns the stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ * @qbman_version: QBMAN version
+ */
+struct dpio_attr {
+ int id;
+ uint64_t qbman_portal_ce_offset;
+ uint64_t qbman_portal_ci_offset;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+ uint32_t qbman_version;
+ uint32_t clk;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+/**
+ * dpio_get_api_version() - Get Data Path I/O API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path i/o API
+ * @minor_ver: Minor version of data path i/o API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPIO_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpio_cmd.h b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
new file mode 100644
index 0000000..e40ec28
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
@@ -0,0 +1,114 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPIO_CMD_H
+#define _FSL_DPIO_CMD_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 4
+#define DPIO_VER_MINOR 2
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPIO_CMDID_OPEN ((0x803 << 4) | (0x1))
+#define DPIO_CMDID_CREATE ((0x903 << 4) | (0x1))
+#define DPIO_CMDID_DESTROY ((0x983 << 4) | (0x1))
+#define DPIO_CMDID_GET_API_VERSION ((0xa03 << 4) | (0x1))
+
+#define DPIO_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPIO_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPIO_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPIO_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPIO_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPIO_CMDID_SET_STASHING_DEST ((0x120 << 4) | (0x1))
+#define DPIO_CMDID_GET_STASHING_DEST ((0x121 << 4) | (0x1))
+#define DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL ((0x122 << 4) | (0x1))
+#define DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL ((0x123 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 2, enum dpio_channel_mode, \
+ cfg->channel_mode);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->num_priorities);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
+ MC_RSP_OP(cmd, 3, 0, 32, uint32_t, attr->qbman_version);\
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, attr->clk);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_SET_STASHING_DEST(cmd, sdest) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_STASHING_DEST(cmd, sdest) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, channel_index) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, channel_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index d49dda8..daf6b8f 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -1,5 +1,13 @@
DPDK_17.02 {
global:
+
+ dpio_close;
+ dpio_disable;
+ dpio_enable;
+ dpio_get_attributes;
+ dpio_open;
+ dpio_reset;
+ dpio_set_stashing_destination;
dpni_close;
dpni_disable;
dpni_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 08/33] bus/fslmc: add mc dpbp object support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (8 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 07/33] bus/fslmc: add mc dpio " Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 09/33] bus/fslmc: add mc dpseci " Hemant Agrawal
` (25 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
DPBP object represent a hw based buffer pool instance
in the DPAA2 hardware.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpbp.c | 230 +++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 220 +++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 76 ++++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 5 +
5 files changed, 532 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index fa1ce13..412715d 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpbp.c b/drivers/bus/fslmc/mc/dpbp.c
new file mode 100644
index 0000000..2260d86
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpbp.c
@@ -0,0 +1,230 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpbp.h>
+#include <fsl_dpbp_cmd.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ (void)(cfg); /* unused */
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPBP_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp.h b/drivers/bus/fslmc/mc/fsl_dpbp.h
new file mode 100644
index 0000000..966989d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp.h
@@ -0,0 +1,220 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpbp_id: DPBP unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpbp_create function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_cfg - Structure representing DPBP configuration
+ * @options: place holder
+ */
+struct dpbp_cfg {
+ uint32_t options;
+};
+
+/**
+ * dpbp_create() - Create the DPBP object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPBP object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpbp_destroy() - Destroy the DPBP object and release all its resources.
+ * @dprc_token: Parent container token; '0' for default container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_is_enabled() - Check if the DPBP is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ uint16_t bpid;
+};
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/**
+ * dpbp_get_api_version() - Get buffer pool API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path buffer pool API
+ * @minor_ver: Minor version of data path buffer pool API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPBP_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
new file mode 100644
index 0000000..4e95054
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
@@ -0,0 +1,76 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPBP_CMD_H
+#define _FSL_DPBP_CMD_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 3
+#define DPBP_VER_MINOR 2
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPBP_CMDID_OPEN ((0x804 << 4) | (0x1))
+#define DPBP_CMDID_CREATE ((0x904 << 4) | (0x1))
+#define DPBP_CMDID_DESTROY ((0x984 << 4) | (0x1))
+#define DPBP_CMDID_GET_API_VERSION ((0xa04 << 4) | (0x1))
+
+#define DPBP_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPBP_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPBP_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPBP_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPBP_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPBP_CMD_H */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index daf6b8f..5167262 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -1,6 +1,11 @@
DPDK_17.02 {
global:
+ dpbp_disable;
+ dpbp_enable;
+ dpbp_get_attributes;
+ dpbp_open;
+ dpbp_reset;
dpio_close;
dpio_disable;
dpio_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 09/33] bus/fslmc: add mc dpseci object support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (9 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 08/33] bus/fslmc: add mc dpbp " Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 10/33] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
` (24 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Cristian Sovaiala, Hemant Agrawal
dpseci represent a instance of SEC HW in DPAA2.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpseci.c | 527 ++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 661 +++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 248 ++++++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 10 +
5 files changed, 1447 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 412715d..e422861 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpseci.c \
mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpseci.c b/drivers/bus/fslmc/mc/dpseci.c
new file mode 100644
index 0000000..173a40c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpseci.c
@@ -0,0 +1,527 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpseci.h>
+#include <fsl_dpseci_cmd.h>
+
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPSECI_CMD_OPEN(cmd, dpseci_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPSECI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_IS_ENABLED,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ(cmd, *type, irq_cfg);
+
+ return 0;
+}
+
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_ENABLE(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_MASK(cmd, *mask);
+
+ return 0;
+}
+
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_STATUS(cmd, *status);
+
+ return 0;
+}
+
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLEAR_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_RX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_RX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_TX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_TX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_TX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_COUNTERS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters);
+
+ return 0;
+}
+
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPSECI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci.h b/drivers/bus/fslmc/mc/fsl_dpseci.h
new file mode 100644
index 0000000..644e30c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci.h
@@ -0,0 +1,661 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPSECI_H
+#define __FSL_DPSECI_H
+
+/* Data Path SEC Interface API
+ * Contains initialization APIs and runtime control APIs for DPSECI
+ */
+
+struct fsl_mc_io;
+
+/**
+ * General DPSECI macros
+ */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPSECI object
+ */
+#define DPSECI_PRIO_NUM 8
+
+/**
+ * All queues considered; see dpseci_set_rx_queue()
+ */
+#define DPSECI_ALL_QUEUES (uint8_t)(-1)
+
+/**
+ * dpseci_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpseci_id: DPSECI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpseci_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token);
+
+/**
+ * dpseci_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_cfg - Structure representing DPSECI configuration
+ * @num_tx_queues: num of queues towards the SEC
+ * @num_rx_queues: num of queues back from the SEC
+ * @priorities: Priorities for the SEC hardware processing;
+ * each place in the array is the priority of the tx queue
+ * towards the SEC,
+ * valid priorities are configured with values 1-8;
+ */
+struct dpseci_cfg {
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+ uint8_t priorities[DPSECI_PRIO_NUM];
+};
+
+/**
+ * dpseci_create() - Create the DPSECI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPSECI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpseci_destroy() - Destroy the DPSECI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpseci_enable() - Enable the DPSECI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_disable() - Disable the DPSECI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_is_enabled() - Check if the DPSECI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpseci_reset() - Reset the DPSECI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_irq_cfg - IRQ configuration
+ * @addr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+ * @irq_num: A user defined number associated with this IRQ
+ */
+struct dpseci_irq_cfg {
+ uint64_t addr;
+ uint32_t val;
+ int irq_num;
+};
+
+/**
+ * dpseci_set_irq() - Set IRQ information for the DPSECI to trigger an interrupt
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: Identifies the interrupt index to configure
+ * @irq_cfg: IRQ configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_get_irq() - Get IRQ information from the DPSECI
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @type: Interrupt type: 0 represents message interrupt
+ * type (both irq_addr and irq_val are valid)
+ * @irq_cfg: IRQ attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_set_irq_enable() - Set overall interrupt state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Interrupt state - enable = 1, disable = 0
+ *
+ * Allows GPP software to control when interrupts are generated.
+ * Each interrupt can have up to 32 causes. The enable/disable control's the
+ * overall interrupt state. if the interrupt is disabled no causes will cause
+ * an interrupt
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en);
+
+/**
+ * dpseci_get_irq_enable() - Get overall interrupt state
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Returned Interrupt state - enable = 1, disable = 0
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en);
+
+/**
+ * dpseci_set_irq_mask() - Set interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: event mask to trigger interrupt;
+ * each bit:
+ * 0 = ignore event
+ * 1 = consider event for asserting IRQ
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask);
+
+/**
+ * dpseci_get_irq_mask() - Get interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: Returned event mask to trigger interrupt
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask);
+
+/**
+ * dpseci_get_irq_status() - Get the current status of any pending interrupts
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: Returned interrupts status - one bit per cause:
+ * 0 = no interrupt pending
+ * 1 = interrupt pending
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status);
+
+/**
+ * dpseci_clear_irq_status() - Clear a pending interrupt's status
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: bits to clear (W1C) - one bit per cause:
+ * 0 = don't change
+ * 1 = clear status bit
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status);
+
+/**
+ * struct dpseci_attr - Structure representing DPSECI attributes
+ * @id: DPSECI object ID
+ * @num_tx_queues: number of queues towards the SEC
+ * @num_rx_queues: number of queues back from the SEC
+ */
+struct dpseci_attr {
+ int id;
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+};
+
+/**
+ * dpseci_get_attributes() - Retrieve DPSECI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr);
+
+/**
+ * enum dpseci_dest - DPSECI destination types
+ * @DPSECI_DEST_NONE: Unassigned destination; The queue is set in parked mode
+ * and does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPSECI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPSECI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpseci_dest {
+ DPSECI_DEST_NONE = 0,
+ DPSECI_DEST_DPIO = 1,
+ DPSECI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpseci_dest_cfg - Structure representing DPSECI destination parameters
+ * @dest_type: Destination type
+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
+ * are 0-1 or 0-7, depending on the number of priorities in that
+ * channel; not relevant for 'DPSECI_DEST_NONE' option
+ */
+struct dpseci_dest_cfg {
+ enum dpseci_dest dest_type;
+ int dest_id;
+ uint8_t priority;
+};
+
+/**
+ * DPSECI queue modification options
+ */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPSECI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPSECI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Select to modify the queue's order preservation
+ */
+#define DPSECI_QUEUE_OPT_ORDER_PRESERVATION 0x00000004
+
+/**
+ * struct dpseci_rx_queue_cfg - DPSECI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ * Use any combination of 'DPSECI_QUEUE_OPT_<X>' flags
+ * @order_preservation_en: order preservation configuration for the rx queue
+ * valid only if 'DPSECI_QUEUE_OPT_ORDER_PRESERVATION' is contained in 'options'
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame;
+ * valid only if 'DPSECI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ * valid only if 'DPSECI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpseci_rx_queue_cfg {
+ uint32_t options;
+ int order_preservation_en;
+ uint64_t user_ctx;
+ struct dpseci_dest_cfg dest_cfg;
+};
+
+/**
+ * dpseci_set_rx_queue() - Set Rx queue configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation; use
+ * DPSECI_ALL_QUEUES to configure all Rx queues identically.
+ * @cfg: Rx queue configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg);
+
+/**
+ * struct dpseci_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame
+ * @order_preservation_en: Status of the order preservation configuration
+ * on the queue
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpseci_rx_queue_attr {
+ uint64_t user_ctx;
+ int order_preservation_en;
+ struct dpseci_dest_cfg dest_cfg;
+ uint32_t fqid;
+};
+
+/**
+ * dpseci_get_rx_queue() - Retrieve Rx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Rx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr);
+
+/**
+ * struct dpseci_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to SEC hardware
+ * @priority: SEC hardware processing priority for the queue
+ */
+struct dpseci_tx_queue_attr {
+ uint32_t fqid;
+ uint8_t priority;
+};
+
+/**
+ * dpseci_get_tx_queue() - Retrieve Tx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Tx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr);
+
+/**
+ * struct dpseci_sec_attr - Structure representing attributes of the SEC
+ * hardware accelerator
+ * @ip_id: ID for SEC.
+ * @major_rev: Major revision number for SEC.
+ * @minor_rev: Minor revision number for SEC.
+ * @era: SEC Era.
+ * @deco_num: The number of copies of the DECO that are implemented in
+ * this version of SEC.
+ * @zuc_auth_acc_num: The number of copies of ZUCA that are implemented
+ * in this version of SEC.
+ * @zuc_enc_acc_num: The number of copies of ZUCE that are implemented
+ * in this version of SEC.
+ * @snow_f8_acc_num: The number of copies of the SNOW-f8 module that are
+ * implemented in this version of SEC.
+ * @snow_f9_acc_num: The number of copies of the SNOW-f9 module that are
+ * implemented in this version of SEC.
+ * @crc_acc_num: The number of copies of the CRC module that are implemented
+ * in this version of SEC.
+ * @pk_acc_num: The number of copies of the Public Key module that are
+ * implemented in this version of SEC.
+ * @kasumi_acc_num: The number of copies of the Kasumi module that are
+ * implemented in this version of SEC.
+ * @rng_acc_num: The number of copies of the Random Number Generator that are
+ * implemented in this version of SEC.
+ * @md_acc_num: The number of copies of the MDHA (Hashing module) that are
+ * implemented in this version of SEC.
+ * @arc4_acc_num: The number of copies of the ARC4 module that are implemented
+ * in this version of SEC.
+ * @des_acc_num: The number of copies of the DES module that are implemented
+ * in this version of SEC.
+ * @aes_acc_num: The number of copies of the AES module that are implemented
+ * in this version of SEC.
+ **/
+
+struct dpseci_sec_attr {
+ uint16_t ip_id;
+ uint8_t major_rev;
+ uint8_t minor_rev;
+ uint8_t era;
+ uint8_t deco_num;
+ uint8_t zuc_auth_acc_num;
+ uint8_t zuc_enc_acc_num;
+ uint8_t snow_f8_acc_num;
+ uint8_t snow_f9_acc_num;
+ uint8_t crc_acc_num;
+ uint8_t pk_acc_num;
+ uint8_t kasumi_acc_num;
+ uint8_t rng_acc_num;
+ uint8_t md_acc_num;
+ uint8_t arc4_acc_num;
+ uint8_t des_acc_num;
+ uint8_t aes_acc_num;
+};
+
+/**
+ * dpseci_get_sec_attr() - Retrieve SEC accelerator attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned SEC attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr);
+
+/**
+ * struct dpseci_sec_counters - Structure representing global SEC counters and
+ * not per dpseci counters
+ * @dequeued_requests: Number of Requests Dequeued
+ * @ob_enc_requests: Number of Outbound Encrypt Requests
+ * @ib_dec_requests: Number of Inbound Decrypt Requests
+ * @ob_enc_bytes: Number of Outbound Bytes Encrypted
+ * @ob_prot_bytes: Number of Outbound Bytes Protected
+ * @ib_dec_bytes: Number of Inbound Bytes Decrypted
+ * @ib_valid_bytes: Number of Inbound Bytes Validated
+ */
+struct dpseci_sec_counters {
+ uint64_t dequeued_requests;
+ uint64_t ob_enc_requests;
+ uint64_t ib_dec_requests;
+ uint64_t ob_enc_bytes;
+ uint64_t ob_prot_bytes;
+ uint64_t ib_dec_bytes;
+ uint64_t ib_valid_bytes;
+};
+
+/**
+ * dpseci_get_sec_counters() - Retrieve SEC accelerator counters.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @counters: Returned SEC counters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters);
+
+/**
+ * dpseci_get_api_version() - Get Data Path SEC Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path sec API
+ * @minor_ver: Minor version of data path sec API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPSECI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
new file mode 100644
index 0000000..a2fb071
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
@@ -0,0 +1,248 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPSECI_CMD_H
+#define _FSL_DPSECI_CMD_H
+
+/* DPSECI Version */
+#define DPSECI_VER_MAJOR 5
+#define DPSECI_VER_MINOR 0
+
+/* Command IDs */
+#define DPSECI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPSECI_CMDID_OPEN ((0x809 << 4) | (0x1))
+#define DPSECI_CMDID_CREATE ((0x909 << 4) | (0x1))
+#define DPSECI_CMDID_DESTROY ((0x989 << 4) | (0x1))
+#define DPSECI_CMDID_GET_API_VERSION ((0xa09 << 4) | (0x1))
+
+#define DPSECI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPSECI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPSECI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPSECI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPSECI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_IRQ ((0x010 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ ((0x011 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_ENABLE ((0x012 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_ENABLE ((0x013 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_MASK ((0x014 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_MASK ((0x015 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_STATUS ((0x016 << 4) | (0x1))
+#define DPSECI_CMDID_CLEAR_IRQ_STATUS ((0x017 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_RX_QUEUE ((0x194 << 4) | (0x1))
+#define DPSECI_CMDID_GET_RX_QUEUE ((0x196 << 4) | (0x1))
+#define DPSECI_CMDID_GET_TX_QUEUE ((0x197 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_ATTR ((0x198 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_COUNTERS ((0x199 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_OPEN(cmd, dpseci_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpseci_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->priorities[0]);\
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, cfg->priorities[1]);\
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->priorities[2]);\
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->priorities[3]);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->priorities[4]);\
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->priorities[5]);\
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->priorities[6]);\
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->priorities[7]);\
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->num_tx_queues);\
+ MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->num_rx_queues);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ(cmd, type, irq_cfg) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+ MC_RSP_OP(cmd, 2, 32, 32, int, type); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, enable_state) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, enable_state); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, enable_state)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_MASK(cmd, mask) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_STATUS(cmd, status) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->num_tx_queues); \
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->num_rx_queues); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue); \
+ MC_CMD_OP(cmd, 0, 48, 4, enum dpseci_dest, cfg->dest_cfg.dest_type); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
+ MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\
+ MC_CMD_OP(cmd, 2, 32, 1, int, cfg->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_RX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_RX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 48, 4, enum dpseci_dest, attr->dest_cfg.dest_type);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint64_t, attr->user_ctx);\
+ MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 2, 32, 1, int, attr->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_TX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_TX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->priority);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, attr->ip_id);\
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->major_rev);\
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, attr->minor_rev);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->era);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->deco_num);\
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->zuc_auth_acc_num);\
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, attr->zuc_enc_acc_num);\
+ MC_RSP_OP(cmd, 1, 32, 8, uint8_t, attr->snow_f8_acc_num);\
+ MC_RSP_OP(cmd, 1, 40, 8, uint8_t, attr->snow_f9_acc_num);\
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, attr->crc_acc_num);\
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->pk_acc_num);\
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->kasumi_acc_num);\
+ MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->rng_acc_num);\
+ MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->md_acc_num);\
+ MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->arc4_acc_num);\
+ MC_RSP_OP(cmd, 2, 48, 8, uint8_t, attr->des_acc_num);\
+ MC_RSP_OP(cmd, 2, 56, 8, uint8_t, attr->aes_acc_num);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, counters->dequeued_requests);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counters->ob_enc_requests);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, counters->ib_dec_requests);\
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, counters->ob_enc_bytes);\
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, counters->ob_prot_bytes);\
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, counters->ib_dec_bytes);\
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, counters->ib_valid_bytes);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPSECI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 5167262..c4b3408 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -35,6 +35,16 @@ DPDK_17.02 {
dpni_set_rx_tc_dist;
dpni_set_tx_confirmation_mode;
dpni_set_unicast_promisc;
+ dpseci_close;
+ dpseci_disable;
+ dpseci_enable;
+ dpseci_get_attributes;
+ dpseci_get_rx_queue;
+ dpseci_get_sec_counters;
+ dpseci_get_tx_queue;
+ dpseci_open;
+ dpseci_reset;
+ dpseci_set_rx_queue;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 10/33] eal/vfio: adding vfio utility functions in map file
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (10 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 09/33] bus/fslmc: add mc dpseci " Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 17:16 ` Thomas Monjalon
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support Hemant Agrawal
` (23 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
adding extra vfio utility functions to map file.
They will be used by other vfio supported buses like fslmc bus
for NXP DPAA2 devices
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +++
2 files changed, 6 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2cf1ac8..e1e0532 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -183,5 +183,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 3c68ff5..99d4446 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -187,5 +187,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (11 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 10/33] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 17:23 ` Thomas Monjalon
2017-01-19 19:12 ` Ferruh Yigit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 12/33] bus/fslmc: scan for net and sec devices Hemant Agrawal
` (22 subsequent siblings)
35 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 | 10 +
drivers/bus/fslmc/fslmc_vfio.c | 450 +++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 74 ++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 2 +
6 files changed, 539 insertions(+)
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 e422861..a5a05de 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 8a4f519..ee794e7 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -42,6 +42,7 @@
#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)
@@ -51,6 +52,15 @@
static int
rte_fslmc_scan(void)
{
+ if (fslmc_vfio_setup_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup VFIO");
+ return -1;
+ }
+ if (fslmc_vfio_process_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
+ return -1;
+ }
+ 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
new file mode 100644
index 0000000..d51e33a
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -0,0 +1,450 @@
+/*-
+ * 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_FSL_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, ®_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(void)
+{
+ 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)
+{
+ struct fslmc_vfio_group *group = NULL;
+ int groupid;
+ int ret, 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;
+ }
+ /* get group number */
+ ret = vfio_get_group_no(SYSFS_FSL_MC_DEVICES, container, &groupid);
+ if (ret == 0) {
+ RTE_LOG(WARNING, EAL, "%s not managed by VFIO, skipping\n",
+ container);
+ return 1;
+ }
+
+ /* if negative, something failed */
+ if (ret < 0)
+ return -1;
+
+ 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;
+ }
+ }
+
+ /* get the actual group fd */
+ group->fd = vfio_get_group_fd(groupid);
+ if (group->fd < 0)
+ return -1;
+
+ /*
+ * at this point, we know that this group is viable (meaning,
+ * all devices are either bound to VFIO or not bound to anything)
+ */
+
+ 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..5e58211
--- /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(void);
+
+#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index c4b3408..411200c 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -45,8 +45,10 @@ DPDK_17.02 {
dpseci_open;
dpseci_reset;
dpseci_set_rx_queue;
+ mcp_ptr_list;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ vfio_dmamap_mem_region;
local: *;
};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support Hemant Agrawal
@ 2017-01-19 17:23 ` Thomas Monjalon
2017-01-20 4:58 ` Hemant Agrawal
2017-01-19 19:12 ` Ferruh Yigit
1 sibling, 1 reply; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-19 17:23 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
2017-01-19 18:53, Hemant Agrawal:
> @@ -45,8 +45,10 @@ DPDK_17.02 {
> dpseci_open;
> dpseci_reset;
> dpseci_set_rx_queue;
> + mcp_ptr_list;
> rte_fslmc_driver_register;
> rte_fslmc_driver_unregister;
> + vfio_dmamap_mem_region;
These symbols do not comply with the DPDK namespace (rte_*).
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support
2017-01-19 17:23 ` Thomas Monjalon
@ 2017-01-20 4:58 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-20 4:58 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
On 1/19/2017 10:53 PM, Thomas Monjalon wrote:
> 2017-01-19 18:53, Hemant Agrawal:
>> @@ -45,8 +45,10 @@ DPDK_17.02 {
>> dpseci_open;
>> dpseci_reset;
>> dpseci_set_rx_queue;
>> + mcp_ptr_list;
>> rte_fslmc_driver_register;
>> rte_fslmc_driver_unregister;
>> + vfio_dmamap_mem_region;
>
> These symbols do not comply with the DPDK namespace (rte_*).
>
We can add the rte_* for the bus exported functions.
do you have a concerns w.r.t dpseci_open type symbols also?
How do we do it?
They are only required to be added in map to resolve the dependency of
PMD on BUS.
These are low level functions provided by the mc bus and referenced by
the different NXP PMDs e.g. NET or CRYPTO, they are not suppose to be
externally exposed functions.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support Hemant Agrawal
2017-01-19 17:23 ` Thomas Monjalon
@ 2017-01-19 19:12 ` Ferruh Yigit
1 sibling, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-19 19:12 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> 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>
<...>
> diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
> index c4b3408..411200c 100644
> --- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
> +++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
> @@ -45,8 +45,10 @@ DPDK_17.02 {
> dpseci_open;
> dpseci_reset;
> dpseci_set_rx_queue;
> + mcp_ptr_list;
> rte_fslmc_driver_register;
> rte_fslmc_driver_unregister;
> + vfio_dmamap_mem_region;
This function seems called by files within bus folder, does it need to
be exported? Not tested, just asking..
>
> local: *;
> };
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 12/33] bus/fslmc: scan for net and sec devices
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (12 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 11/33] bus/fslmc: add vfio support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
` (21 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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_vfio.c | 63 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index d51e33a..fd844e2 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -210,6 +210,48 @@ 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 != DPAA2_MC_DPNI_DEVID ||
+ dev->dev_type != DPAA2_MC_DPSECI_DEVID)
+ return -1;
+
+ if (dev->object_id == dev2->object_id)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+fslmc_bus_add_device(struct rte_dpaa2_device *dev)
+{
+ struct rte_fslmc_device_list *dev_l;
+
+ dev_l = &rte_fslmc_bus.device_list;
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(dev_l)) {
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ } else {
+ struct rte_dpaa2_device *dev2;
+ int ret;
+
+ TAILQ_FOREACH(dev2, dev_l, next) {
+ ret = dpaa2_compare_dpaa2_dev(dev, dev2);
+ if (ret <= 0)
+ continue;
+
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ return;
+ }
+
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ }
+}
+
/* Following function shall fetch total available list of MC devices
* from VFIO container & populate private list of devices and other
* data structures
@@ -218,7 +260,7 @@ int fslmc_vfio_process_group(void)
{
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;
@@ -348,6 +390,25 @@ int fslmc_vfio_process_group(void)
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);
+
+ fslmc_bus_add_device(dev);
+ }
}
closedir(d);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (13 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 12/33] bus/fslmc: scan for net and sec devices Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 19:15 ` Ferruh Yigit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 14/33] bus/fslmc: add debug log message support Hemant Agrawal
` (20 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 4 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/bus/Makefile | 2 +
drivers/common/Makefile | 2 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 59 +++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 153 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 ++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 5 +
10 files changed, 279 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
diff --git a/config/common_base b/config/common_base
index e6b4d60..6f513fe 100644
--- a/config/common_base
+++ b/config/common_base
@@ -297,6 +297,10 @@ CONFIG_RTE_LIBRTE_DPAA2_COMMON=n
#
CONFIG_RTE_LIBRTE_FSLMC_BUS=n
+#
+# Compile burst-oriented NXP DPAA2 PMD driver
+#
+CONFIG_RTE_LIBRTE_DPAA2_PMD=n
# Compile burst-oriented VIRTIO PMD driver
#
CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 800e22b..13c16c0 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -51,3 +51,8 @@ CONFIG_RTE_LIBRTE_DPAA2_COMMON=y
# Compile NXP DPAA2 FSL-MC Bus
#
CONFIG_RTE_LIBRTE_FSLMC_BUS=y
+
+#
+# Compile burst-oriented NXP DPAA2 PMD driver
+#
+CONFIG_RTE_LIBRTE_DPAA2_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 60e9764..8f7864b 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -31,6 +31,8 @@
include $(RTE_SDK)/mk/rte.vars.mk
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+
DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index e5bfecb..76ec2d1 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,8 @@
include $(RTE_SDK)/mk/rte.vars.mk
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+
DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 40fc333..f716ca0 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -57,7 +57,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
-
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
endif # $(CONFIG_RTE_LIBRTE_VHOST)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
new file mode 100644
index 0000000..9e7f958
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,59 @@
+# BSD LICENSE
+#
+# Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# Copyright (c) 2016 NXP. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Freescale Semiconductor, Inc nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_fslmcbus
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
new file mode 100644
index 0000000..2295f82
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,153 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (c) 2016 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <time.h>
+#include <net/if.h>
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_string_fns.h>
+#include <rte_cycles.h>
+#include <rte_kvargs.h>
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_fslmc.h>
+
+#include <fslmc_vfio.h>
+#include "dpaa2_ethdev.h"
+
+/* Name of the DPAA2 Net PMD */
+static const char *drivername = "DPAA2 PMD";
+
+static int
+dpaa2_dev_init(struct rte_eth_dev *eth_dev)
+{
+ /* For secondary processes, the primary has done all the work */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ eth_dev->data->drv_name = drivername;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = (struct eth_driver *)dpaa2_drv;
+
+ sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ sizeof(struct dpaa2_dev_priv),
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL) {
+ RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
+ " private port data\n");
+ return -ENOMEM;
+ }
+ }
+ eth_dev->device = &dpaa2_dev->device;
+ dpaa2_dev->eth_dev = eth_dev;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(ð_dev->link_intr_cbs);
+
+ /*
+ * Set the default MTU.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .driver = {
+ .name = "DPAA2 PMD",
+ },
+ .probe = rte_dpaa2_probe,
+ .remove = rte_dpaa2_remove,
+};
+
+
+RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd);
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
new file mode 100644
index 0000000..5778780
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -0,0 +1,44 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (c) 2016 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DPAA2_ETHDEV_H
+#define _DPAA2_ETHDEV_H
+
+struct dpaa2_dev_priv {
+ void *hw;
+ int32_t hw_id;
+ uint16_t token;
+
+ uint8_t flags; /*dpaa2 config flags */
+};
+#endif /* _DPAA2_ETHDEV_H */
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
new file mode 100644
index 0000000..31eca32
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.02 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a5daa84..c793dd2 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -110,6 +110,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_fslmcbus
+endif
_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
_LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
@ 2017-01-19 19:15 ` Ferruh Yigit
2017-01-20 14:01 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-19 19:15 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
> add support for fsl-mc bus based dpaa2 pmd driver.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
<...>
> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
> index e5bfecb..76ec2d1 100644
> --- a/drivers/common/Makefile
> +++ b/drivers/common/Makefile
> @@ -31,6 +31,8 @@
>
> include $(RTE_SDK)/mk/rte.vars.mk
>
> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
This logic make sense, is there any reason DPAA2_COMMON to be a config
option, it doesn't look like something a user would like to change on
its own.
Instead, as done here, if there is a user of common folder it is enabled
in Makefile. For this DPAA2_COMMON doesn't need to be a config option
itself I think.
> +
> DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
>
> include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 40fc333..f716ca0 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -57,7 +57,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
> -
> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
Add alphabetically please.
> ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
> endif # $(CONFIG_RTE_LIBRTE_VHOST)
<...>
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> new file mode 100644
> index 0000000..2295f82
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
<...>
> +/* Name of the DPAA2 Net PMD */
> +static const char *drivername = "DPAA2 PMD";
Custom names not preferred, please check any other PMD to be consistent.
<...>
> +static int
> +rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
> + struct rte_dpaa2_device *dpaa2_dev)
> +{
> + struct eth_driver *eth_drv;
whitespace error.
> + struct rte_eth_dev *eth_dev;
> + char ethdev_name[RTE_ETH_NAME_MAX_LEN];
> +
> + int diag;
> +
> + eth_drv = (struct eth_driver *)dpaa2_drv;
How this suppose to work?
struct eth_driver {
struct rte_pci_driver pci_drv;
eth_dev_init_t eth_dev_init;
eth_dev_uninit_t eth_dev_uninit;
unsigned int dev_private_size;
};
struct rte_dpaa2_driver {
TAILQ_ENTRY(rte_dpaa2_driver) next;
struct rte_driver driver;
struct rte_fslmc_bus *fslmc_bus;
uint32_t drv_flags;
uint16_t drv_type;
rte_dpaa2_probe_t probe
rte_dpaa2_remove_t remove;
};
> +
> + sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
> +
> + eth_dev = rte_eth_dev_allocate(ethdev_name);
> + if (eth_dev == NULL)
> + return -ENOMEM;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + eth_dev->data->dev_private = rte_zmalloc(
> + "ethdev private structure",
> + sizeof(struct dpaa2_dev_priv),
> + RTE_CACHE_LINE_SIZE);
> + if (eth_dev->data->dev_private == NULL) {
> + RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
> + " private port data\n");
> + return -ENOMEM;
release allocated port?
> + }
> + }
> + eth_dev->device = &dpaa2_dev->device;
> + dpaa2_dev->eth_dev = eth_dev;
> + eth_dev->driver = eth_drv;
> + eth_dev->data->rx_mbuf_alloc_failed = 0;
> +
> + /* init user callbacks */
> + TAILQ_INIT(ð_dev->link_intr_cbs);
This is no more required, since done by rte_eth_dev_allocate()
> +
> + /*
> + * Set the default MTU.
> + */
> + eth_dev->data->mtu = ETHER_MTU;
Same, no more required to set in pmd.
> +
> + /* Invoke PMD device initialization function */
> + diag = dpaa2_dev_init(eth_dev);
> + if (diag == 0)
> + return 0;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eth_dev->data->dev_private);
> + rte_eth_dev_release_port(eth_dev);
> + return diag;
> +}
<...>
> +static struct rte_dpaa2_driver rte_dpaa2_pmd = {
> + .drv_type = DPAA2_MC_DPNI_DEVID,
> + .driver = {
> + .name = "DPAA2 PMD",
This is not required, RTE_PMD_REGISTER_DPAA2 will set it.
> + },
> + .probe = rte_dpaa2_probe,
> + .remove = rte_dpaa2_remove,
These are PMD specific APIs, PCI equivalent of these are eth_dev_init()
and eth_dev_uninit() functions. Instead of rte_eth_dev_pci_probe() like
function.
Here it seems used as how it is used for virtual devices. But even for
virtual devices, it is desired to have more proper virtual bus structure.
I understand this part is a little problematic now, because of the
eth_driver <-> pci_driver relation, this is not generic.
What do you think first solve eth_driver <-> pci_driver problem, out of
this patchset, and later add this PMD?
<...>
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index a5daa84..c793dd2 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -110,6 +110,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
> _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
> _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
> _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
If DPAA2_COMMON removed it can work here too, because if DPAA2_PMD
enabled, DPAA2_COMMON should be already enabled.
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2_qbman
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_fslmcbus
> +endif
> _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
> _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
> _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-19 19:15 ` Ferruh Yigit
@ 2017-01-20 14:01 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-20 14:01 UTC (permalink / raw)
To: Ferruh Yigit, Hemant Agrawal
Cc: dev, thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob
Hello Ferruh,
On Friday 20 January 2017 12:45 AM, Ferruh Yigit wrote:
> On 1/19/2017 1:23 PM, Hemant Agrawal wrote:
>> add support for fsl-mc bus based dpaa2 pmd driver.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> <...>
>
>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>> index e5bfecb..76ec2d1 100644
>> --- a/drivers/common/Makefile
>> +++ b/drivers/common/Makefile
>> @@ -31,6 +31,8 @@
>>
>> include $(RTE_SDK)/mk/rte.vars.mk
>>
>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>
> This logic make sense, is there any reason DPAA2_COMMON to be a config
> option, it doesn't look like something a user would like to change on
> its own.
I am assuming you wanted to say "The logic _doesn't_ make sense, ..." :)
>
> Instead, as done here, if there is a user of common folder it is enabled
> in Makefile. For this DPAA2_COMMON doesn't need to be a config option
> itself I think.
Aim of drivers/common was to introduce libraries which may be used by
more than one sub-system. These can be other than dpaa2 and may even
be external to DPDK framework itself.
But for now, we will remove it and keep it toggleable with rte.app.mk
changes. Maybe in future, if need for configurable option exist, we will
introduce.
>
>> +
>> DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += dpaa2
>>
>> include $(RTE_SDK)/mk/rte.subdir.mk
>> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
>> index 40fc333..f716ca0 100644
>> --- a/drivers/net/Makefile
>> +++ b/drivers/net/Makefile
>> @@ -57,7 +57,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
>> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
>> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
>> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
>> -
>> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
>
> Add alphabetically please.
Agree.
>
>> ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
>> DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
>> endif # $(CONFIG_RTE_LIBRTE_VHOST)
>
> <...>
>
>> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
>> new file mode 100644
>> index 0000000..2295f82
>> --- /dev/null
>> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> <...>
>> +/* Name of the DPAA2 Net PMD */
>> +static const char *drivername = "DPAA2 PMD";
>
> Custom names not preferred, please check any other PMD to be consistent.
Yes, this should be changed.
>
> <...>
>
>> +static int
>> +rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
>> + struct rte_dpaa2_device *dpaa2_dev)
>> +{
>> + struct eth_driver *eth_drv;
>
> whitespace error.
Fixed. Thanks.
>
>> + struct rte_eth_dev *eth_dev;
>> + char ethdev_name[RTE_ETH_NAME_MAX_LEN];
>> +
>> + int diag;
>> +
>> + eth_drv = (struct eth_driver *)dpaa2_drv;
>
> How this suppose to work?
Actually, a not-so-clean-logic coupled with the above line which
probably got added in one of our rebasing attempts. And you have pointed
out correctly - because of eth_driver<->pci_driver restriction.
(more below)
>
> struct eth_driver {
>
> struct rte_pci_driver pci_drv;
> eth_dev_init_t eth_dev_init;
> eth_dev_uninit_t eth_dev_uninit;
> unsigned int dev_private_size;
> };
>
> struct rte_dpaa2_driver {
> TAILQ_ENTRY(rte_dpaa2_driver) next;
> struct rte_driver driver;
> struct rte_fslmc_bus *fslmc_bus;
> uint32_t drv_flags;
> uint16_t drv_type;
> rte_dpaa2_probe_t probe
> rte_dpaa2_remove_t remove;
> };
dpaa2 driver is not using eth_drv - it is more of a dummy.
If we had used rte_eth_dev_pci_probe, we would have faced this issue of
delinking eth_driver from pci_probe. So, we have leveraged the
bus->probe and created our own probing routine (rather than use
rte_eth_dev_pci_probe).
Then, because it is our own probe routine, we simply allocate the
eth_dev (which luckily is free from pci_dev), and call our dev_init,
which rte_eth_dev_pci_probe would have done using eth_drv->init().
(More below)
>
>> +
>> + sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
>> +
>> + eth_dev = rte_eth_dev_allocate(ethdev_name);
>> + if (eth_dev == NULL)
>> + return -ENOMEM;
>> +
>> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
>> + eth_dev->data->dev_private = rte_zmalloc(
>> + "ethdev private structure",
>> + sizeof(struct dpaa2_dev_priv),
>> + RTE_CACHE_LINE_SIZE);
>> + if (eth_dev->data->dev_private == NULL) {
>> + RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
>> + " private port data\n");
>> + return -ENOMEM;
>
> release allocated port?
Yes, I will fix this.
>
>> + }
>> + }
>> + eth_dev->device = &dpaa2_dev->device;
>> + dpaa2_dev->eth_dev = eth_dev;
>> + eth_dev->driver = eth_drv;
>> + eth_dev->data->rx_mbuf_alloc_failed = 0;
>> +
>> + /* init user callbacks */
>> + TAILQ_INIT(ð_dev->link_intr_cbs);
>
> This is no more required, since done by rte_eth_dev_allocate()
yes, through eth_dev_get. Thanks - next version will contain the fix.
>
>> +
>> + /*
>> + * Set the default MTU.
>> + */
>> + eth_dev->data->mtu = ETHER_MTU;
>
> Same, no more required to set in pmd.
Yes, thanks for highlighting. Implementing our own rte_eth_dev_pci_probe
meant writing all these ourselves which we couldn't match to the changes
being done upstream.
>
>> +
>> + /* Invoke PMD device initialization function */
>> + diag = dpaa2_dev_init(eth_dev);
>> + if (diag == 0)
>> + return 0;
>> +
>> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
>> + rte_free(eth_dev->data->dev_private);
>> + rte_eth_dev_release_port(eth_dev);
>> + return diag;
>> +}
>
> <...>
>
>> +static struct rte_dpaa2_driver rte_dpaa2_pmd = {
>> + .drv_type = DPAA2_MC_DPNI_DEVID,
>> + .driver = {
>> + .name = "DPAA2 PMD",
>
> This is not required, RTE_PMD_REGISTER_DPAA2 will set it.
Yes. Will be removed.
>
>> + },
>> + .probe = rte_dpaa2_probe,
>> + .remove = rte_dpaa2_remove,
>
> These are PMD specific APIs, PCI equivalent of these are eth_dev_init()
> and eth_dev_uninit() functions. Instead of rte_eth_dev_pci_probe() like
> function.
> Here it seems used as how it is used for virtual devices. But even for
> virtual devices, it is desired to have more proper virtual bus structure.
>
> I understand this part is a little problematic now, because of the
> eth_driver <-> pci_driver relation, this is not generic.
> What do you think first solve eth_driver <-> pci_driver problem, out of
> this patchset, and later add this PMD?
This is a long pending problem. I agree that it would be cleaner to do
this unlink. But, I think that the current way dpaa2 driver handles it
is not truly incorrect.
bus->probe() can be linked to a driver specific probe (which dpaa2
does). A PCI PMD would have called rte_eth_dev_pci_probe() as a helper
for doing all eth_dev/eth_drv initialization. dpaa2 does it manually.
I agree we need to match up to various changes done in
rte_eth_dev_pci_probe(), but after that our code is as legal as any
other PMD :D.
>
> <...>
>
>> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>> index a5daa84..c793dd2 100644
>> --- a/mk/rte.app.mk
>> +++ b/mk/rte.app.mk
>> @@ -110,6 +110,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_COMMON),y)
>
> If DPAA2_COMMON removed it can work here too, because if DPAA2_PMD
> enabled, DPAA2_COMMON should be already enabled.
Agreed.
>
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2_qbman
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_fslmcbus
>> +endif
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 14/33] bus/fslmc: add debug log message support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (14 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 13/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 15/33] drivers/common/dpaa2: dpio portal driver Hemant Agrawal
` (19 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 | 9 +++-
7 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
diff --git a/config/common_base b/config/common_base
index 6f513fe..9d35487 100644
--- a/config/common_base
+++ b/config/common_base
@@ -301,6 +301,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 a5a05de..b74c333 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 9e7f958..cfe51d6 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 2295f82..5f74a11 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -54,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;
@@ -66,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;
@@ -96,8 +101,8 @@
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 15/33] drivers/common/dpaa2: dpio portal driver
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (15 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 14/33] bus/fslmc: add debug log message support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 16/33] drivers/pool/dpaa2: adding hw offloaded mempool Hemant Agrawal
` (18 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
The portal 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 | 3 +
drivers/bus/fslmc/fslmc_vfio.c | 17 +-
drivers/bus/fslmc/fslmc_vfio.h | 5 +
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 364 +++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 60 ++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 68 +++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 2 +
drivers/common/Makefile | 4 +
8 files changed, 522 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index b74c333..1b815dd 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -46,6 +46,7 @@ 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)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -61,10 +62,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpio.c \
mc/mc_sys.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_pmd_dpaa2_qbman
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index fd844e2..8d24620 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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
#define VFIO_MAX_CONTAINERS 1
#define FSLMC_VFIO_LOG(level, fmt, args...) \
@@ -261,12 +264,13 @@ int fslmc_vfio_process_group(void)
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;
@@ -409,9 +413,20 @@ int fslmc_vfio_process_group(void)
fslmc_bus_add_device(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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5e58211..39994dd 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -71,4 +71,9 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(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_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
new file mode 100644
index 0000000..011bd9f
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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, ®_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, ®_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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
new file mode 100644
index 0000000..682f3fa
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -0,0 +1,60 @@
+/*-
+ * 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_DPIO_H_
+#define _DPAA2_HW_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);
+
+
+#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
new file mode 100644
index 0000000..ef3eb71
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 411200c..4236377 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -1,6 +1,7 @@
DPDK_17.02 {
global:
+ dpaa2_affine_qbman_swp;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
@@ -46,6 +47,7 @@ DPDK_17.02 {
dpseci_reset;
dpseci_set_rx_queue;
mcp_ptr_list;
+ per_lcore__dpaa2_io;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
vfio_dmamap_mem_region;
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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (16 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 15/33] drivers/common/dpaa2: dpio portal driver Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads Hemant Agrawal
` (17 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 | 2 +
drivers/bus/fslmc/fslmc_vfio.c | 9 +-
drivers/bus/fslmc/fslmc_vfio.h | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 +++++++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 19 ++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 2 +
drivers/common/Makefile | 3 +
drivers/pool/Makefile | 38 +++
drivers/pool/dpaa2/Makefile | 67 +++++
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339 ++++++++++++++++++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++
drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map | 8 +
mk/rte.app.mk | 1 +
16 files changed, 727 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
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 9d35487..5a10e45 100644
--- a/config/common_base
+++ b/config/common_base
@@ -291,6 +291,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..9fd268e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
DIRS-y += bus
+DIRS-y += pool
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 1b815dd..35f30ad 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -47,6 +47,7 @@ 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/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -63,6 +64,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 8d24620..2bfd7fd 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -270,7 +270,7 @@ int fslmc_vfio_process_group(void)
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 +420,11 @@ int fslmc_vfio_process_group(void)
if (!ret)
dpio_count++;
}
+ if (!strcmp(object_type, "dpbp")) {
+ ret = dpaa2_create_dpbp_device(object_id);
+ if (!ret)
+ dpbp_count++;
+ }
}
closedir(d);
@@ -427,6 +432,8 @@ int fslmc_vfio_process_group(void)
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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 39994dd..80c6869 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -76,4 +76,6 @@ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
struct vfio_device_info *obj_info,
int object_id);
+int dpaa2_create_dpbp_device(int dpbp_id);
+
#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
new file mode 100644
index 0000000..16d5b24
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
@@ -0,0 +1,137 @@
+/*-
+ * 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_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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
+TAILQ_HEAD(dpbp_device_list, dpaa2_dpbp_dev);
+static struct dpbp_device_list *dpbp_dev_list; /*!< DPBP device list */
+
+int
+dpaa2_create_dpbp_device(
+ int dpbp_id)
+{
+ struct dpaa2_dpbp_dev *dpbp_node;
+ int ret;
+
+ if (!dpbp_dev_list) {
+ dpbp_dev_list = malloc(sizeof(struct dpbp_device_list));
+ if (!dpbp_dev_list) {
+ PMD_INIT_LOG(ERR, "Memory alloc failed in DPBP list\n");
+ return -1;
+ }
+ /* Initialize the DPBP List */
+ TAILQ_INIT(dpbp_dev_list);
+ }
+
+ /* Allocate DPAA2 dpbp handle */
+ dpbp_node = (struct dpaa2_dpbp_dev *)
+ malloc(sizeof(struct dpaa2_dpbp_dev));
+ 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;
+ rte_atomic16_init(&dpbp_node->in_use);
+
+ TAILQ_INSERT_HEAD(dpbp_dev_list, dpbp_node, next);
+
+ PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
+
+ return 0;
+}
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Get DPBP dev handle from list using index */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
+ break;
+ }
+
+ return dpbp_dev;
+}
+
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Match DPBP handle and mark it free */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev == dpbp) {
+ rte_atomic16_dec(&dpbp_dev->in_use);
+ return;
+ }
+ }
+}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index ef3eb71..3b846a0 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -63,6 +70,18 @@ struct dpaa2_dpio_dev {
int32_t hw_id; /**< An unique ID of this DPIO device instance */
};
+struct dpaa2_dpbp_dev {
+ TAILQ_ENTRY(dpaa2_dpbp_dev) next;
+ /**< Pointer to Next device instance */
+ struct fsl_mc_io dpbp; /** handle to DPBP portal object */
+ uint16_t token;
+ rte_atomic16_t in_use;
+ uint32_t dpbp_id; /*HW ID for DPBP object */
+};
+
/*! Global MCP list */
extern void *(*mcp_ptr_list);
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
+
#endif
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 4236377..76029b9 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -2,6 +2,8 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_alloc_dpbp_dev;
+ dpaa2_free_dpbp_dev;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
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/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..9494756
--- /dev/null
+++ b/drivers/pool/dpaa2/Makefile
@@ -0,0 +1,67 @@
+# 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/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-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += lib/librte_pmd_dpaa2_qbman
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += lib/librte_pmd_fslmcbus
+
+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..f36e909
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -0,0 +1,339 @@
+/*-
+ * 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 <mc/fsl_dpbp.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+#include "dpaa2_hw_mempool.h"
+
+struct dpaa2_bp_info bpid_info[MAX_BPID];
+static struct dpaa2_bp_list *h_bp_list;
+
+static int
+hw_mbuf_create_pool(struct rte_mempool *mp)
+{
+ struct dpaa2_bp_list *bp_list;
+ struct dpaa2_dpbp_dev *avail_dpbp;
+ struct dpbp_attr dpbp_attr;
+ uint32_t bpid;
+ int ret;
+
+ avail_dpbp = dpaa2_alloc_dpbp_dev();
+
+ if (!avail_dpbp) {
+ PMD_DRV_LOG(ERR, "DPAA2 resources not available");
+ return -1;
+ }
+
+ if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+ ret = dpaa2_affine_qbman_swp();
+ if (ret) {
+ RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+ return 0;
+ }
+ }
+
+ 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;
+
+
+ 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)
+{
+ struct dpaa2_bp_info *bpinfo;
+ struct dpaa2_bp_list *bp;
+ struct dpaa2_dpbp_dev *dpbp_node;
+
+ if (!mp->pool_data) {
+ PMD_DRV_LOG(ERR, "Not a valid dpaa22 pool");
+ return;
+ }
+
+ bpinfo = (struct dpaa2_bp_info *)mp->pool_data;
+ bp = bpinfo->bp_list;
+ dpbp_node = bp->buf_pool.dpbp_node;
+
+ dpbp_disable(&(dpbp_node->dpbp), CMD_PRI_LOW, dpbp_node->token);
+
+ if (h_bp_list == bp) {
+ h_bp_list = h_bp_list->next;
+ } else { /* if it is not the first node */
+ struct dpaa2_bp_list *prev = h_bp_list, *temp;
+ temp = h_bp_list->next;
+ while (temp) {
+ if (temp == bp) {
+ prev->next = temp->next;
+ free(bp);
+ break;
+ }
+ prev = temp;
+ temp = temp->next;
+ }
+ }
+
+ dpaa2_free_dpbp_dev(dpbp_node);
+}
+
+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..2cd2564
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
@@ -0,0 +1,95 @@
+/*-
+ * 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 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 dpaa2_dpbp_dev *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 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..289ab10
--- /dev/null
+++ b/drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map
@@ -0,0 +1,8 @@
+DPDK_17.02 {
+ global:
+
+ bpid_info;
+ hw_mbuf_alloc_bulk;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c793dd2..f415c18 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -113,6 +113,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_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (17 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 16/33] drivers/pool/dpaa2: adding hw offloaded mempool Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 18/33] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (16 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 45 ++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 3 ++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 1 +
3 files changed, 49 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index 011bd9f..d7de0d5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index 682f3fa..b1a1b8f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -56,5 +56,8 @@ 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);
+
#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 76029b9..6937ad0 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -2,6 +2,7 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
dpaa2_free_dpbp_dev;
dpbp_disable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 18/33] net/dpaa2: adding eth ops to dpaa2
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (18 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 19/33] net/dpaa2: add rss flow distribution Hemant Agrawal
` (15 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++
drivers/net/dpaa2/Makefile | 3 +
drivers/net/dpaa2/dpaa2_ethdev.c | 412 +++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
5 files changed, 450 insertions(+), 1 deletion(-)
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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 3b846a0..660537d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -79,6 +82,23 @@ struct dpaa2_dpbp_dev {
uint32_t dpbp_id; /*HW ID for DPBP object */
};
+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);
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index cfe51d6..61831cc 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -46,6 +46,8 @@ 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
@@ -59,6 +61,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_fslmcbus
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 5f74a11..484add4 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,33 +47,443 @@
#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 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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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;
+ }
+
+ 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;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 19/33] net/dpaa2: add rss flow distribution
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (19 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 18/33] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 20/33] net/dpaa2: configure mac address at init Hemant Agrawal
` (14 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 61831cc..657ee2a 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 484add4..1d7ca66 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 20/33] net/dpaa2: configure mac address at init
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (20 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 19/33] net/dpaa2: add rss flow distribution Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 21/33] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (13 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 1d7ca66..54f4498 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 21/33] net/dpaa2: attach the buffer pool to dpni
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (21 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 20/33] net/dpaa2: configure mac address at init Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 22/33] net/dpaa2: add support for l3 and l4 checksum offload Hemant Agrawal
` (12 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_pvt.h | 10 ++++++
drivers/net/dpaa2/Makefile | 3 ++
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, 138 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 660537d..b4f243b 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 657ee2a..ca51402 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -62,7 +63,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_fslmcbus
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
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 54f4498..6bd18bc 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 22/33] net/dpaa2: add support for l3 and l4 checksum offload
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (22 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 21/33] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 23/33] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (11 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 +
drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index b4f243b..71361a4 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 6bd18bc..b85e31f 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 23/33] net/dpaa2: add support for promiscuous mode
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (23 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 22/33] net/dpaa2: add support for l3 and l4 checksum offload Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 24/33] net/dpaa2: add mtu config support Hemant Agrawal
` (10 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 b85e31f..76d8e6d 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 24/33] net/dpaa2: add mtu config support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (24 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 23/33] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 25/33] net/dpaa2: add packet rx and tx support Hemant Agrawal
` (9 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 71361a4..7c6cc7e 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 76d8e6d..f98e7b8 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 25/33] net/dpaa2: add packet rx and tx support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (25 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 24/33] net/dpaa2: add mtu config support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 26/33] net/dpaa2: rx packet parsing and packet type support Hemant Agrawal
` (8 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 7c6cc7e..158dfef 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
@@ -121,6 +127,54 @@ 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
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index ca51402..5e669df 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 f98e7b8..448aac7 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 26/33] net/dpaa2: rx packet parsing and packet type support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (26 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 25/33] net/dpaa2: add packet rx and tx support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 27/33] net/dpaa2: link status update Hemant Agrawal
` (7 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 448aac7..cbcf806 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 27/33] net/dpaa2: link status update
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (27 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 26/33] net/dpaa2: rx packet parsing and packet type support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 28/33] net/dpaa2: basic stats support Hemant Agrawal
` (6 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 cbcf806..70264b6 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 28/33] net/dpaa2: basic stats support
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (28 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 27/33] net/dpaa2: link status update Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 29/33] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (5 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 70264b6..a9d5f10 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 29/33] net/dpaa2: enable stashing for LS2088A devices
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (29 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 28/33] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 30/33] net/dpaa2: add support for non hw buffer pool packet transmit Hemant Agrawal
` (4 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 a9d5f10..2cf395f 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 30/33] net/dpaa2: add support for non hw buffer pool packet transmit
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (30 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 29/33] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 31/33] net/dpaa2: enabling the use of physical addresses Hemant Agrawal
` (3 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 31/33] net/dpaa2: enabling the use of physical addresses
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (31 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 30/33] net/dpaa2: add support for non hw buffer pool packet transmit Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 32/33] bus/fslmc: add support for dmamap to ARM SMMU Hemant Agrawal
` (2 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_pvt.h | 66 +++++++++++++++++++++++++++++++
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, 95 insertions(+), 12 deletions(-)
diff --git a/config/common_base b/config/common_base
index 5a10e45..ebd6281 100644
--- a/config/common_base
+++ b/config/common_base
@@ -292,6 +292,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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 158dfef..052a171 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -175,6 +175,72 @@ 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 */
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
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 f36e909..3875d7c 100644
--- a/drivers/pool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -203,9 +203,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);
@@ -214,8 +219,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,
@@ -288,6 +300,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 32/33] bus/fslmc: add support for dmamap to ARM SMMU
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (32 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 31/33] net/dpaa2: enabling the use of physical addresses Hemant Agrawal
@ 2017-01-19 13:23 ` Hemant Agrawal
2017-01-19 13:24 ` [dpdk-dev] [PATCHv5 33/33] drivers/common/dpaa2: frame queue based dq storage alloc Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:23 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 96 ++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 1 +
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 2 +
4 files changed, 100 insertions(+)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 2bfd7fd..bea32b5 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -76,8 +76,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)
{
@@ -147,6 +149,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,71 @@ 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 80c6869..7d562d3 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -70,6 +70,7 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(void);
+int fslmc_vfio_dmamap(void);
/* create dpio device */
int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
diff --git a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 6937ad0..17befc7 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -49,6 +49,7 @@ DPDK_17.02 {
dpseci_open;
dpseci_reset;
dpseci_set_rx_queue;
+ fslmc_vfio_dmamap;
mcp_ptr_list;
per_lcore__dpaa2_io;
rte_fslmc_driver_register;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 2cf395f..183b5b1 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv5 33/33] drivers/common/dpaa2: frame queue based dq storage alloc
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (33 preceding siblings ...)
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 32/33] bus/fslmc: add support for dmamap to ARM SMMU Hemant Agrawal
@ 2017-01-19 13:24 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-19 13:24 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_dpio.c | 32 ++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 7 ++++++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 8 +++----
4 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index d7de0d5..55b5ad7 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index b1a1b8f..f2e1168 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -59,5 +59,12 @@ struct dpaa2_io_portal_t {
/* Affine additional DPIO portal to current crypto processing thread */
int dpaa2_affine_qbman_swp_sec(void);
+/* 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/bus/fslmc/rte_pmd_fslmcbus_version.map b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
index 17befc7..bccdc75 100644
--- a/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
+++ b/drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
@@ -4,7 +4,9 @@ DPDK_17.02 {
dpaa2_affine_qbman_swp;
dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
+ dpaa2_alloc_dq_storage;
dpaa2_free_dpbp_dev;
+ dpaa2_free_dq_storage;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 183b5b1..695ee61 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-19 13:23 ` [dpdk-dev] [PATCHv5 00/33] NXP DPAA2 PMD Hemant Agrawal
` (34 preceding siblings ...)
2017-01-19 13:24 ` [dpdk-dev] [PATCHv5 33/33] drivers/common/dpaa2: frame queue based dq storage alloc Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 01/33] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
` (35 more replies)
35 siblings, 36 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
fsl-mc bus driver and network SoC PMD. This version of the driver
supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fsl-mc’, part of Linux Kernel Staging tree [3], for resource management.
A brief description of architecture is given below; detailed description
is part of the documentation in the patches itself.
DPAA2 contains hardware component called the Management Complex (or MC).
It manages the DPAA2 hardware resources. The MC provides an object-based
abstraction for software drivers to use the DPAA2 hardware.
Some of the key objects are:
- DPNI, which refers to the network interface object.
- DPBP, which refers to HW based memory pool object
- DPIO, refers to processing context for accessing QBMAN
Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
software/user-space to the queues and buffers implemented in the hardware.
The patch series could be logically structured into following sub-areas:
1. (Patch 0001) Enabling crc in armv8 core machine type
2. (Patch 0002) Common dpaa2 hw accelerator drivers for QBMAN.
3. (Patches 0003-0017) introduce fsl-mc bus, dpaa2 pmd, DPIO and mempool
4. (Patches 0018-0031) Support for DPAA2 Ethernet Device (ethdev)
5. (Patches 0032-0033) Additional functionality in DPAA2 ethdev.
The following design decisions are made during development:
1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
These drivers will be shared with dpaa2 based crypto drivers.
2. DPAA2 implements the HW mempool offload with DPBP object.
- The new pool is being configured using compile time option and pool name
as "dpaa2".
3. It maintains per lcore DPIO objects and affine the DPIO instance to the
processing threads accessing the QBMAN HW.
Prerequisites:
- For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
- At present the series has limited support for Ethernet functions. But,
more functionality would be made available in a phased manner.
Future Changes/Caveats:
1. VFIO code for fsl-mc bus is different than eal-vfio code for pci bus.
This need to be re-worked to make possible re-use of the existing code.
2. shared lib support in case of parallel build fails due to dependency of
drivers/common, pool, etc on other driver components. The dependency graph
need to be improved to support it.
References:
[1] http://dpdk.org/dev/patchwork/patch/19557/
[2] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[3] http://dpdk.org/ml/archives/dev/2016-October/048949.html
---
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (33):
mk/dpaa2: add the crc support to the machine type
drivers/common/dpaa2: adding qbman driver
bus/fslmc: introducing fsl-mc bus driver
bus/fslmc: introduce mc object functions
bus/fslmc: add mc dpni object support
bus/fslmc: add mc dpio object support
bus/fslmc: add mc dpbp object support
bus/fslmc: add mc dpseci object support
eal/vfio: adding vfio utility functions in map file
bus/fslmc: add vfio support
bus/fslmc: scan for net and sec devices
net/dpaa2: introducing NXP dpaa2 pmd driver
doc: add dpaa2 nic details
bus/fslmc: add debug log message support
drivers/common/dpaa2: dpio portal driver
drivers/pool/dpaa2: adding hw offloaded mempool
drivers/common/dpaa2: dpio routine to affine to crypto threads
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add rss flow distribution
net/dpaa2: configure mac address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for l3 and l4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add mtu config support
net/dpaa2: add packet rx and tx support
net/dpaa2: rx packet parsing and packet type support
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: add support for non hw buffer pool packet transmit
net/dpaa2: enabling the use of physical addresses
bus/fslmc: add support for dmamap to ARM SMMU
drivers/common/dpaa2: frame queue based dq storage alloc
MAINTAINERS | 8 +
config/common_base | 21 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 27 +-
doc/guides/nics/dpaa2.rst | 593 ++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
drivers/Makefile | 3 +
drivers/bus/Makefile | 38 +
drivers/bus/fslmc/Makefile | 79 ++
drivers/bus/fslmc/fslmc_bus.c | 135 ++
drivers/bus/fslmc/fslmc_logs.h | 76 +
drivers/bus/fslmc/fslmc_vfio.c | 629 ++++++++
drivers/bus/fslmc/fslmc_vfio.h | 82 ++
drivers/bus/fslmc/mc/dpbp.c | 237 ++++
drivers/bus/fslmc/mc/dpio.c | 279 ++++
drivers/bus/fslmc/mc/dpni.c | 739 ++++++++++
drivers/bus/fslmc/mc/dpseci.c | 534 +++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 +++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++
drivers/bus/fslmc/mc/fsl_dpkg.h | 184 +++
drivers/bus/fslmc/mc/fsl_dpni.h | 1217 ++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 334 +++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 668 +++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 255 ++++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 ++
drivers/bus/fslmc/mc/fsl_net.h | 487 +++++++
drivers/bus/fslmc/mc/mc_sys.c | 114 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 441 ++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 70 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 247 ++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 61 +
drivers/bus/fslmc/rte_fslmc.h | 148 ++
drivers/common/Makefile | 48 +
drivers/common/dpaa2/Makefile | 48 +
drivers/common/dpaa2/qbman/Makefile | 70 +
drivers/common/dpaa2/qbman/include/compat.h | 406 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 160 +++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1495 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 277 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 170 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 385 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 73 +
.../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 27 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 72 +
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 +++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1042 ++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 ++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
drivers/pool/Makefile | 40 +
drivers/pool/dpaa2/Makefile | 71 +
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 352 +++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
mk/machine/dpaa2/rte.vars.mk | 5 +-
mk/rte.app.mk | 4 +
66 files changed, 15984 insertions(+), 5 deletions(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
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_pool_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 01/33] mk/dpaa2: add the crc support to the machine type
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
` (34 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
mk/machine/dpaa2/rte.vars.mk | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mk/machine/dpaa2/rte.vars.mk b/mk/machine/dpaa2/rte.vars.mk
index 8541633..e4735c2 100644
--- a/mk/machine/dpaa2/rte.vars.mk
+++ b/mk/machine/dpaa2/rte.vars.mk
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -53,7 +54,7 @@
# CPU_CFLAGS =
# CPU_LDFLAGS =
# CPU_ASFLAGS =
-MACHINE_CFLAGS += -march=armv8-a
+MACHINE_CFLAGS += -march=armv8-a+crc
ifdef CONFIG_RTE_ARCH_ARM_TUNE
MACHINE_CFLAGS += -mcpu=$(CONFIG_RTE_ARCH_ARM_TUNE)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 01/33] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 17:30 ` Ferruh Yigit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 03/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
` (33 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Geoff Thorpe, Roy Pledge,
Hemant Agrawal
QBMAN, is a hardware block which interfaces with the other
accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
SoC for queue, buffer and packet scheduling.
This patch introduces a userspace driver for interfacing with
the QBMAN hw block.
The qbman-portal component provides APIs to do the low level
hardware bit twiddling for operations such as:
-initializing Qman software portals
-building and sending portal commands
-portal interrupt configuration and processing
This same/similar code is used in kernel and compat file is used
to make it working in user space.
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 4 +
config/common_base | 1 -
config/defconfig_arm64-dpaa2-linuxapp-gcc | 3 +-
drivers/Makefile | 1 +
drivers/common/Makefile | 36 +
drivers/common/dpaa2/Makefile | 36 +
drivers/common/dpaa2/qbman/Makefile | 53 +
drivers/common/dpaa2/qbman/include/compat.h | 406 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 160 +++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1495 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 277 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 170 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 385 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 73 +
.../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 27 +
16 files changed, 4218 insertions(+), 2 deletions(-)
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index f071138..5ad150d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -354,6 +354,10 @@ M: Alejandro Lucero <alejandro.lucero@netronome.com>
F: drivers/net/nfp/
F: doc/guides/nics/nfp.rst
+NXP dpaa2
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/common/dpaa2/
+
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/config/common_base b/config/common_base
index b9fb8e2..5564d92 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,7 +287,6 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=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 66df54c..da23bab 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
diff --git a/drivers/Makefile b/drivers/Makefile
index 81c03a8..d5580f6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -31,6 +31,7 @@
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..e5bfecb
--- /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_COMMON) += dpaa2
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
new file mode 100644
index 0000000..4960ebe
--- /dev/null
+++ b/drivers/common/dpaa2/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_COMMON) += qbman
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
new file mode 100644
index 0000000..5e64d23
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -0,0 +1,53 @@
+# 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_common_dpaa2_qbman.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+
+EXPORT_MAP := rte_common_dpaa2_qbman_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += \
+ qbman_portal.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/common/dpaa2/qbman/include/compat.h b/drivers/common/dpaa2/qbman/include/compat.h
new file mode 100644
index 0000000..28d7952
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/compat.h
@@ -0,0 +1,406 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 HEADER_COMPAT_H
+#define HEADER_COMPAT_H
+
+#include <sched.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <net/ethernet.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <assert.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <error.h>
+#include <rte_atomic.h>
+
+/* The following definitions are primarily to allow the single-source driver
+ * interfaces to be included by arbitrary program code. Ie. for interfaces that
+ * are also available in kernel-space, these definitions provide compatibility
+ * with certain attributes and types used in those interfaces.
+ */
+
+/* Required compiler attributes */
+#define __user
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+#undef container_of
+#define container_of(ptr, type, member) ({ \
+ typeof(((type *)0)->member)(*__mptr) = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#ifdef ARRAY_SIZE
+#undef ARRAY_SIZE
+#endif
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/* Required types */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uint64_t dma_addr_t;
+typedef cpu_set_t cpumask_t;
+typedef u32 compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+/* I/O operations */
+static inline u32 in_be32(volatile void *__p)
+{
+ volatile u32 *p = __p;
+ return *p;
+}
+
+static inline void out_be32(volatile void *__p, u32 val)
+{
+ volatile u32 *p = __p;
+ *p = val;
+}
+
+/* Debugging */
+#define prflush(fmt, args...) \
+ do { \
+ printf(fmt, ##args); \
+ fflush(stdout); \
+ } while (0)
+#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args)
+#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args)
+#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args)
+#define pr_info(fmt, args...) prflush(fmt, ##args)
+
+#ifdef pr_debug
+#undef pr_debug
+#endif
+#define pr_debug(fmt, args...) {}
+#define might_sleep_if(c) {}
+#define msleep(x) {}
+#define WARN_ON(c, str) \
+do { \
+ static int warned_##__LINE__; \
+ if ((c) && !warned_##__LINE__) { \
+ pr_warn("%s\n", str); \
+ pr_warn("(%s:%d)\n", __FILE__, __LINE__); \
+ warned_##__LINE__ = 1; \
+ } \
+} while (0)
+#define QBMAN_BUG_ON(c) WARN_ON(c, "BUG")
+
+#define ALIGN(x, a) (((x) + ((typeof(x))(a) - 1)) & ~((typeof(x))(a) - 1))
+
+/****************/
+/* Linked-lists */
+/****************/
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_HEAD(n) \
+struct list_head n = { \
+ .prev = &n, \
+ .next = &n \
+}
+
+#define INIT_LIST_HEAD(p) \
+do { \
+ struct list_head *__p298 = (p); \
+ __p298->next = __p298; \
+ __p298->prev = __p298->next; \
+} while (0)
+#define list_entry(node, type, member) \
+ (type *)((void *)node - offsetof(type, member))
+#define list_empty(p) \
+({ \
+ const struct list_head *__p298 = (p); \
+ ((__p298->next == __p298) && (__p298->prev == __p298)); \
+})
+#define list_add(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->next = __l298->next; \
+ __p298->prev = __l298; \
+ __l298->next->prev = __p298; \
+ __l298->next = __p298; \
+} while (0)
+#define list_add_tail(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->prev = __l298->prev; \
+ __p298->next = __l298; \
+ __l298->prev->next = __p298; \
+ __l298->prev = __p298; \
+} while (0)
+#define list_for_each(i, l) \
+ for (i = (l)->next; i != (l); i = i->next)
+#define list_for_each_safe(i, j, l) \
+ for (i = (l)->next, j = i->next; i != (l); \
+ i = j, j = i->next)
+#define list_for_each_entry(i, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \
+ i = list_entry(i->name.next, typeof(*i), name))
+#define list_for_each_entry_safe(i, j, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name), \
+ j = list_entry(i->name.next, typeof(*j), name); \
+ &i->name != (l); \
+ i = j, j = list_entry(j->name.next, typeof(*j), name))
+#define list_del(i) \
+do { \
+ (i)->next->prev = (i)->prev; \
+ (i)->prev->next = (i)->next; \
+} while (0)
+
+/* Other miscellaneous interfaces our APIs depend on; */
+
+#define lower_32_bits(x) ((u32)(x))
+#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16))
+
+/* Compiler/type stuff */
+typedef unsigned int gfp_t;
+typedef uint32_t phandle;
+
+#define __iomem
+#define EINTR 4
+#define ENODEV 19
+#define GFP_KERNEL 0
+#define __raw_readb(p) (*(const volatile unsigned char *)(p))
+#define __raw_readl(p) (*(const volatile unsigned int *)(p))
+#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); }
+
+/* memcpy() stuff - when you know alignments in advance */
+#ifdef CONFIG_TRY_BETTER_MEMCPY
+static inline void copy_words(void *dest, const void *src, size_t sz)
+{
+ u32 *__dest = dest;
+ const u32 *__src = src;
+ size_t __sz = sz >> 2;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x3);
+ QBMAN_BUG_ON((unsigned long)src & 0x3);
+ QBMAN_BUG_ON(sz & 0x3);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_shorts(void *dest, const void *src, size_t sz)
+{
+ u16 *__dest = dest;
+ const u16 *__src = src;
+ size_t __sz = sz >> 1;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x1);
+ QBMAN_BUG_ON((unsigned long)src & 0x1);
+ QBMAN_BUG_ON(sz & 0x1);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_bytes(void *dest, const void *src, size_t sz)
+{
+ u8 *__dest = dest;
+ const u8 *__src = src;
+
+ while (sz--)
+ *(__dest++) = *(__src++);
+}
+#else
+#define copy_words memcpy
+#define copy_shorts memcpy
+#define copy_bytes memcpy
+#endif
+
+/* Completion stuff */
+#define DECLARE_COMPLETION(n) int n = 0
+#define complete(n) { *n = 1; }
+#define wait_for_completion(n) \
+do { \
+ while (!*n) { \
+ bman_poll(); \
+ qman_poll(); \
+ } \
+ *n = 0; \
+} while (0)
+
+/* Allocator stuff */
+#define kmalloc(sz, t) malloc(sz)
+#define vmalloc(sz) malloc(sz)
+#define kfree(p) { if (p) free(p); }
+static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused)
+{
+ void *ptr = malloc(sz);
+
+ if (ptr)
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
+{
+ void *p;
+
+ if (posix_memalign(&p, 4096, 4096))
+ return 0;
+ memset(p, 0, 4096);
+ return (unsigned long)p;
+}
+
+static inline void free_page(unsigned long p)
+{
+ free((void *)p);
+}
+
+/* Bitfield stuff. */
+#define BITS_PER_ULONG (sizeof(unsigned long) << 3)
+#define SHIFT_PER_ULONG (((1 << 5) == BITS_PER_ULONG) ? 5 : 6)
+#define BITS_MASK(idx) ((unsigned long)1 << ((idx) & (BITS_PER_ULONG - 1)))
+#define BITS_IDX(idx) ((idx) >> SHIFT_PER_ULONG)
+static inline unsigned long test_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ return *p & mask;
+}
+
+static inline int test_bit(int idx, volatile unsigned long *bits)
+{
+ return test_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void set_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p |= mask;
+}
+
+static inline void set_bit(int idx, volatile unsigned long *bits)
+{
+ set_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p &= ~mask;
+}
+
+static inline void clear_bit(int idx, volatile unsigned long *bits)
+{
+ clear_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline unsigned long test_and_set_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ unsigned long ret = test_bits(mask, p);
+
+ set_bits(mask, p);
+ return ret;
+}
+
+static inline int test_and_set_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ set_bit(idx, bits);
+ return ret;
+}
+
+static inline int test_and_clear_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ clear_bit(idx, bits);
+ return ret;
+}
+
+static inline int find_next_zero_bit(unsigned long *bits, int limit, int idx)
+{
+ while ((++idx < limit) && test_bit(idx, bits))
+ ;
+ return idx;
+}
+
+static inline int find_first_zero_bit(unsigned long *bits, int limit)
+{
+ int idx = 0;
+
+ while (test_bit(idx, bits) && (++idx < limit))
+ ;
+ return idx;
+}
+
+static inline u64 div64_u64(u64 n, u64 d)
+{
+ return n / d;
+}
+
+#define atomic_t rte_atomic32_t
+#define atomic_read(v) rte_atomic32_read(v)
+#define atomic_set(v, i) rte_atomic32_set(v, i)
+
+#define atomic_inc(v) rte_atomic32_add(v, 1)
+#define atomic_dec(v) rte_atomic32_sub(v, 1)
+
+#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v)
+#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v)
+
+#define atomic_inc_return(v) rte_atomic32_add_return(v, 1)
+#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1)
+#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
+
+#endif /* HEADER_COMPAT_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
new file mode 100644
index 0000000..ee4b772
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
@@ -0,0 +1,160 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+typedef uint64_t dma_addr_t;
+
+/**
+ * DOC: QBMan basic structures
+ *
+ * The QBMan block descriptor, software portal descriptor and Frame descriptor
+ * are defined here.
+ *
+ */
+
+#define QMAN_REV_4000 0x04000000
+#define QMAN_REV_4100 0x04010000
+#define QMAN_REV_4101 0x04010001
+
+/**
+ * struct qbman_block_desc - qbman block descriptor structure
+ * @ccsr_reg_bar: CCSR register map.
+ * @irq_rerr: Recoverable error interrupt line.
+ * @irq_nrerr: Non-recoverable error interrupt line
+ *
+ * Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to.
+ */
+struct qbman_block_desc {
+ void *ccsr_reg_bar;
+ int irq_rerr;
+ int irq_nrerr;
+};
+
+enum qbman_eqcr_mode {
+ qman_eqcr_vb_ring = 2, /* Valid bit, with eqcr in ring mode */
+ qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */
+};
+
+/**
+ * struct qbman_swp_desc - qbman software portal descriptor structure
+ * @block: The QBMan instance.
+ * @cena_bar: Cache-enabled portal register map.
+ * @cinh_bar: Cache-inhibited portal register map.
+ * @irq: -1 if unused (or unassigned)
+ * @idx: SWPs within a QBMan are indexed. -1 if opaque to the user.
+ * @qman_version: the qman version.
+ * @eqcr_mode: Select the eqcr mode, currently only valid bit ring mode and
+ * valid bit array mode are supported.
+ *
+ * Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "MC bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering.
+ */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block;
+ uint8_t *cena_bar;
+ uint8_t *cinh_bar;
+ int irq;
+ int idx;
+ uint32_t qman_version;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/**
+ * struct qbman_fd - basci structure for qbman frame descriptor
+ * @words: for easier/faster copying the whole FD structure.
+ * @addr_lo: the lower 32 bits of the address in FD.
+ * @addr_hi: the upper 32 bits of the address in FD.
+ * @len: the length field in FD.
+ * @bpid_offset: represent the bpid and offset fields in FD. offset in
+ * the MS 16 bits, BPID in the LS 16 bits.
+ * @frc: frame context
+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
+ * @flc_lo: the lower 32bit of flow context.
+ * @flc_hi: the upper 32bits of flow context.
+ *
+ * Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ uint32_t bpid_offset;
+ uint32_t frc;
+ uint32_t ctrl;
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
new file mode 100644
index 0000000..7731772
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
@@ -0,0 +1,1093 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl_qbman_base.h>
+
+/**
+ * DOC - QBMan portal APIs to implement the following functions:
+ * - Initialize and destroy Software portal object.
+ * - Read and write Software portal interrupt registers.
+ * - Enqueue, including setting the enqueue descriptor, and issuing enqueue
+ * command etc.
+ * - Dequeue, including setting the dequeue descriptor, issuing dequeue command,
+ * parsing the dequeue response in DQRR and memeory, parsing the state change
+ * notifications etc.
+ * - Release, including setting the release descriptor, and issuing the buffer
+ * release command.
+ * - Acquire, acquire the buffer from the given buffer pool.
+ * - FQ management.
+ * - Channel management, enable/disable CDAN with or without context.
+ */
+
+/**
+ * qbman_swp_init() - Create a functional object representing the given
+ * QBMan portal descriptor.
+ * @d: the given qbman swp descriptor
+ *
+ * Return qbman_swp portal object for success, NULL if the object cannot
+ * be created.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
+
+/**
+ * qbman_swp_finish() - Create and destroy a functional object representing
+ * the given QBMan portal descriptor.
+ * @p: the qbman_swp object to be destroyed.
+ *
+ */
+void qbman_swp_finish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_get_desc() - Get the descriptor of the given portal object.
+ * @p: the given portal object.
+ *
+ * Return the descriptor for this portal.
+ */
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p);
+
+ /**************/
+ /* Interrupts */
+ /**************/
+
+/* EQCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_EQRI ((uint32_t)0x00000001)
+/* Enqueue command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_EQDI ((uint32_t)0x00000002)
+/* DQRR non-empty interrupt */
+#define QBMAN_SWP_INTERRUPT_DQRI ((uint32_t)0x00000004)
+/* RCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_RCRI ((uint32_t)0x00000008)
+/* Release command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_RCDI ((uint32_t)0x00000010)
+/* Volatile dequeue command interrupt */
+#define QBMAN_SWP_INTERRUPT_VDCI ((uint32_t)0x00000020)
+
+/**
+ * qbman_swp_interrupt_get_vanish() - Get the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISDR register.
+ */
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_vanish() - Set the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IDSR register.
+ */
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_read_status() - Get the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISR register.
+ */
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_clear_status() - Set the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_ISR register.
+ */
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_trigger() - Get the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IER register.
+ */
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_trigger() - Set the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IER register.
+ */
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_inhibit() - Get the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IIR register.
+ */
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_inhibit() - Set the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IIR register.
+ */
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/**
+ * struct qbman_result - structure for qbman dequeue response and/or
+ * notification.
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * possible qbman dequeue result.
+ */
+struct qbman_result {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* TODO:
+ *A DQRI interrupt can be generated when there are dequeue results on the
+ * portal's DQRR (this mechanism does not deal with "pull" dequeues to
+ * user-supplied 'storage' addresses). There are two parameters to this
+ * interrupt source, one is a threshold and the other is a timeout. The
+ * interrupt will fire if either the fill-level of the ring exceeds 'thresh', or
+ * if the ring has been non-empty for been longer than 'timeout' nanoseconds.
+ * For timeout, an approximation to the desired nanosecond-granularity value is
+ * made, so there are get and set APIs to allow the user to see what actual
+ * timeout is set (compared to the timeout that was requested).
+ */
+int qbman_swp_dequeue_thresh(struct qbman_swp *s, unsigned int thresh);
+int qbman_swp_dequeue_set_timeout(struct qbman_swp *s, unsigned int timeout);
+int qbman_swp_dequeue_get_timeout(struct qbman_swp *s, unsigned int *timeout);
+
+/* ------------------- */
+/* Push-mode dequeuing */
+/* ------------------- */
+
+/* The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+
+/**
+ * qbman_swp_push_get() - Get the push dequeue setup.
+ * @s: the software portal object.
+ * @channel_idx: the channel index to query.
+ * @enabled: returned boolean to show whether the push dequeue is enabled for
+ * the given channel.
+ */
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled);
+
+/**
+ * qbman_swp_push_set() - Enable or disable push dequeue.
+ * @s: the software portal object.
+ * @channel_idx: the channel index..
+ * @enable: enable or disable push dequeue.
+ *
+ * The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable);
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+/**
+ * struct qbman_pull_desc - the structure for pull dequeue descriptor
+ * @dont_manipulate_directly: the 6 32bit data to represent the whole
+ * possible settings for pull dequeue descriptor.
+ */
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+enum qbman_pull_type_e {
+ /* dequeue with priority precedence, respect intra-class scheduling */
+ qbman_pull_type_prio = 1,
+ /* dequeue with active FQ precedence, respect ICS */
+ qbman_pull_type_active,
+ /* dequeue with active FQ precedence, no ICS */
+ qbman_pull_type_active_noics
+};
+
+/**
+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the pull dequeue descriptor to be cleared.
+ */
+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
+
+/**
+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
+ * @d: the pull dequeue descriptor to be set.
+ * @storage: the pointer of the memory to store the dequeue result.
+ * @storage_phys: the physical address of the storage memory.
+ * @stash: to indicate whether write allocate is enabled.
+ *
+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute.
+ */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/**
+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued.
+ * @d: the pull dequeue descriptor to be set.
+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive.
+ */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
+ uint8_t numframes);
+/**
+ * qbman_pull_desc_set_token() - Set dequeue token for pull command
+ * @d: the dequeue descriptor
+ * @token: the token to be set
+ *
+ * token is the value that shows up in the dequeue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing a dequeue, and use any non-zero 'token' value
+ */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+/**
+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues.
+ * @fqid: the frame queue index of the given FQ.
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid);
+
+/**
+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues.
+ * @wqid: composed of channel id and wqid within the channel.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct);
+
+/* qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
+ * dequeues.
+ * @chid: the channel id to be dequeued.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct);
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object.
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls.
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry.
+ * @s: the software portal object.
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *p);
+
+/**
+ * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
+ * qbman_swp_dqrr_next().
+ * @s: the software portal object.
+ * @dq: the DQRR entry to be consumed.
+ */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct qbman_result *dq);
+
+/**
+ * qbman_get_dqrr_idx() - Get dqrr index from the given dqrr
+ * @dqrr: the given dqrr object.
+ *
+ * Return dqrr index.
+ */
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr);
+
+/**
+ * qbman_get_dqrr_from_idx() - Use index to get the dqrr entry from the
+ * given portal
+ * @s: the given portal.
+ * @idx: the dqrr index.
+ *
+ * Return dqrr entry object.
+ */
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/**
+ * qbman_result_has_new_result() - Check and get the dequeue response from the
+ * dq storage memory set in pull dequeue command
+ * @s: the software portal object.
+ * @dq: the dequeue result read from the memory.
+ *
+ * Only used for user-provided storage of dequeue results, not DQRR. For
+ * efficiency purposes, the driver will perform any required endianness
+ * conversion to ensure that the user's dequeue result storage is in host-endian
+ * format (whether or not that is the same as the little-endian format that
+ * hardware DMA'd to the user's storage). As such, once the user has called
+ * qbman_result_has_new_result() and been returned a valid dequeue result,
+ * they should not call it again on the same memory location (except of course
+ * if another dequeue command has been executed to produce a new result to that
+ * location).
+ *
+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
+ * dequeue result.
+ */
+int qbman_result_has_new_result(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/**
+ * qbman_result_is_DQ() - check the dequeue result is a dequeue response or not
+ * @dq: the dequeue result to be checked.
+ *
+ * DQRR entries may contain non-dequeue results, ie. notifications
+ */
+int qbman_result_is_DQ(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
+ * @dq: the dequeue result to be checked.
+ *
+ * All the non-dequeue results (FQDAN/CDAN/CSCN/...) are "state change
+ * notifications" of one type or another. Some APIs apply to all of them, of the
+ * form qbman_result_SCN_***().
+ */
+static inline int qbman_result_is_SCN(const struct qbman_result *dq)
+{
+ return !qbman_result_is_DQ(dq);
+}
+
+/* Recognise different notification types, only required if the user allows for
+ * these to occur, and cares about them when they do.
+ */
+
+/**
+ * qbman_result_is_FQDAN() - Check for FQ Data Availability
+ * @dq: the qbman_result object.
+ *
+ * Return 1 if this is FQDAN.
+ */
+int qbman_result_is_FQDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CDAN() - Check for Channel Data Availability
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CDAN.
+ */
+int qbman_result_is_CDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CSCN() - Check for Congestion State Change
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CSCN.
+ */
+int qbman_result_is_CSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_BPSCN() - Check for Buffer Pool State Change.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is BPSCN.
+ */
+int qbman_result_is_BPSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CGCU() - Check for Congestion Group Count Update.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CGCU.
+ */
+int qbman_result_is_CGCU(const struct qbman_result *dq);
+
+/* Frame queue state change notifications; (FQDAN in theory counts too as it
+ * leaves a FQ parked, but it is primarily a data availability notification)
+ */
+
+/**
+ * qbman_result_is_FQRN() - Check for FQ Retirement Notification.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRN.
+ */
+int qbman_result_is_FQRN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQRNI() - Check for FQ Retirement Immediate
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRNI.
+ */
+int qbman_result_is_FQRNI(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQPN() - Check for FQ Park Notification
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQPN.
+ */
+int qbman_result_is_FQPN(const struct qbman_result *dq);
+
+/* Parsing frame dequeue results (qbman_result_is_DQ() must be TRUE)
+ */
+/* FQ empty */
+#define QBMAN_DQ_STAT_FQEMPTY 0x80
+/* FQ held active */
+#define QBMAN_DQ_STAT_HELDACTIVE 0x40
+/* FQ force eligible */
+#define QBMAN_DQ_STAT_FORCEELIGIBLE 0x20
+/* Valid frame */
+#define QBMAN_DQ_STAT_VALIDFRAME 0x10
+/* FQ ODP enable */
+#define QBMAN_DQ_STAT_ODPVALID 0x04
+/* Volatile dequeue */
+#define QBMAN_DQ_STAT_VOLATILE 0x02
+/* volatile dequeue command is expired */
+#define QBMAN_DQ_STAT_EXPIRED 0x01
+
+/**
+ * qbman_result_DQ_flags() - Get the STAT field of dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the state field.
+ */
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_is_pull() - Check whether the dq response is from a pull
+ * command.
+ * @dq: the dequeue result.
+ *
+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
+ */
+static inline int qbman_result_DQ_is_pull(const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_VOLATILE);
+}
+
+/**
+ * qbman_result_DQ_is_pull_complete() - Check whether the pull command is
+ * completed.
+ * @dq: the dequeue result.
+ *
+ * Return boolean.
+ */
+static inline int qbman_result_DQ_is_pull_complete(
+ const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_EXPIRED);
+}
+
+/**
+ * qbman_result_DQ_seqnum() - Get the seqnum field in dequeue response
+ * seqnum is valid only if VALIDFRAME flag is TRUE
+ * @dq: the dequeue result.
+ *
+ * Return seqnum.
+ */
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_odpid() - Get the seqnum field in dequeue response
+ * odpid is valid only if ODPVAILD flag is TRUE.
+ * @dq: the dequeue result.
+ *
+ * Return odpid.
+ */
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqid() - Get the fqid in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return fqid.
+ */
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_byte_count() - Get the byte count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the byte count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_frame_count - Get the frame count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqd_ctx() - Get the frame queue context in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame queue context.
+ */
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fd() - Get the frame descriptor in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame descriptor.
+ */
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq);
+
+/* State-change notifications (FQDAN/CDAN/CSCN/...). */
+
+/**
+ * qbman_result_SCN_state() - Get the state field in State-change notification
+ * @scn: the state change notification.
+ *
+ * Return the state in the notifiation.
+ */
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid() - Get the resource id from the notification
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_ctx() - get the context from the notification
+ * @scn: the state change notification.
+ *
+ * Return the context.
+ */
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_state_in_mem() - Get the state in notification written
+ * in memory
+ * @scn: the state change notification.
+ *
+ * Return the state.
+ */
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid_in_mem() - Get the resource id in notification written
+ * in memory.
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn);
+
+/* Type-specific "resource IDs". Mainly for illustration purposes, though it
+ * also gives the appropriate type widths.
+ */
+/* Get the FQID from the FQDAN */
+#define qbman_result_FQDAN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRN */
+#define qbman_result_FQRN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRNI */
+#define qbman_result_FQRNI_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQPN */
+#define qbman_result_FQPN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the channel ID from the CDAN */
+#define qbman_result_CDAN_cid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+/* Get the CGID from the CSCN */
+#define qbman_result_CSCN_cgid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+
+/**
+ * qbman_result_bpscn_bpid() - Get the bpid from BPSCN
+ * @scn: the state change notification.
+ *
+ * Return the buffer pool id.
+ */
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_has_free_bufs() - Check whether there are free
+ * buffers in the pool from BPSCN.
+ * @scn: the state change notification.
+ *
+ * Return the number of free buffers.
+ */
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_depleted() - Check BPSCN to see whether the
+ * buffer pool is depleted.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool depletion.
+ */
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_surplus() - Check BPSCN to see whether the buffer
+ * pool is surplus or not.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool surplus.
+ */
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_ctx() - Get the BPSCN CTX from BPSCN message
+ * @scn: the state change notification.
+ *
+ * Return the BPSCN context.
+ */
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn);
+
+/* Parsing CGCU */
+/**
+ * qbman_result_cgcu_cgid() - Check CGCU resouce id, i.e. cgid
+ * @scn: the state change notification.
+ *
+ * Return the CGCU resource id.
+ */
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_cgcu_icnt() - Get the I_CNT from CGCU
+ * @scn: the state change notification.
+ *
+ * Return instantaneous count in the CGCU notification.
+ */
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+/**
+ * struct qbman_eq_desc - structure of enqueue descriptor
+ * @dont_manipulate_directly: the 8 32bit data to represent the whole
+ * possible qbman enqueue setting in enqueue descriptor.
+ */
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+/**
+ * struct qbman_eq_response - structure of enqueue response
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * enqueue response.
+ */
+struct qbman_eq_response {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/**
+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the given enqueue descriptor.
+ */
+void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+
+/**
+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+/**
+ * qbman_eq_desc_set_orp() - Set order-resotration in the enqueue descriptor
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ * @incomplete: indiates whether this is the last fragments using the same
+ * sequeue number.
+ */
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete);
+
+/**
+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+
+/**
+ * qbman_eq_desc_set_orp_nesn() - advance NESN (Next Expected Sequence Number)
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+/**
+ * qbman_eq_desc_set_response() - Set the enqueue response info.
+ * @d: the enqueue descriptor
+ * @storage_phys: the physical address of the enqueue response in memory.
+ * @stash: indicate that the write allocation enabled or not.
+ *
+ * In the case where an enqueue response is DMA'd, this determines where that
+ * response should go. (The physical/DMA address is given for hardware's
+ * benefit, but software should interpret it as a "struct qbman_eq_response"
+ * data structure.) 'stash' controls whether or not the write to main-memory
+ * expresses a cache-warming attribute.
+ */
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash);
+
+/**
+ * qbman_eq_desc_set_token() - Set token for the enqueue command
+ * @d: the enqueue descriptor
+ * @token: the token to be set.
+ *
+ * token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value.
+ */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token);
+
+/**
+ * Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+/**
+ * qbman_eq_desc_set_fq() - Set Frame Queue id for the enqueue command
+ * @d: the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued.
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid);
+
+/**
+ * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command.
+ * @d: the enqueue descriptor
+ * @qdid: the id of the queuing destination to be enqueued.
+ * @qd_bin: the queuing destination bin
+ * @qd_prio: the queuing destination priority.
+ */
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/**
+ * qbman_eq_desc_set_eqdi() - enable/disable EQDI interrupt
+ * @d: the enqueue descriptor
+ * @enable: boolean to enable/disable EQDI
+ *
+ * Determines whether or not the portal's EQDI interrupt source should be
+ * asserted after the enqueue command is completed.
+ */
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable);
+
+/**
+ * qbman_eq_desc_set_dca() - Set DCA mode in the enqueue command.
+ * @d: the enqueue descriptor.
+ * @enable: enabled/disable DCA mode.
+ * @dqrr_idx: DCAP_CI, the DCAP consumer index.
+ * @park: determine the whether park the FQ or not
+ *
+ * Determines whether or not a portal DQRR entry should be consumed once the
+ * enqueue command is completed. (And if so, and the DQRR entry corresponds to a
+ * held-active (order-preserving) FQ, whether the FQ should be parked instead of
+ * being rescheduled.)
+ */
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park);
+
+/**
+ * qbman_swp_enqueue() - Issue an enqueue command.
+ * @s: the software portal used for enqueue.
+ * @d: the enqueue descriptor.
+ * @fd: the frame descriptor to be enqueued.
+ *
+ * Please note that 'fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".
+ *
+ * Return 0 for a successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd);
+
+/* TODO:
+ * qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt.
+ * @s: the software portal.
+ * @thresh: the threshold to trigger the EQRI interrupt.
+ *
+ * An EQRI interrupt can be generated when the fill-level of EQCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_enqueue_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+/**
+ * struct qbman_release_desc - The structure for buffer release descriptor
+ * @dont_manipulate_directly: the 32bit data to represent the whole
+ * possible settings of qbman release descriptor.
+ */
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/**
+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_clear(struct qbman_release_desc *d);
+
+/**
+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid);
+
+/**
+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
+ * interrupt source should be asserted after the release command is completed.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+
+/**
+ * qbman_swp_release() - Issue a buffer release command.
+ * @s: the software portal object.
+ * @d: the release descriptor.
+ * @buffers: a pointer pointing to the buffer address to be released.
+ * @num_buffers: number of buffers to be released, must be less than 8.
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+/* TODO:
+ * qbman_swp_release_thresh() - Set threshold for RCRI interrupt
+ * @s: the software portal.
+ * @thresh: the threshold.
+ * An RCRI interrupt can be generated when the fill-level of RCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_release_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+/**
+ * qbman_swp_acquire() - Issue a buffer acquire command.
+ * @s: the software portal object.
+ * @bpid: the buffer pool index.
+ * @buffers: a pointer pointing to the acquired buffer address|es.
+ * @num_buffers: number of buffers to be acquired, must be less than 8.
+ *
+ * Return 0 for success, or negative error code if the acquire command
+ * fails.
+ */
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+
+ /*****************/
+ /* FQ management */
+ /*****************/
+/**
+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be scheduled.
+ *
+ * There are a couple of different ways that a FQ can end up parked state,
+ * This schedules it.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be forced.
+ *
+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
+ * and thus be available for selection by any channel-dequeuing behaviour (push
+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
+ * empty at the time this happens, the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * These functions change the FQ flow-control stuff between XON/XOFF. (The
+ * default is XON.) This setting doesn't affect enqueues to the FQ, just
+ * dequeues. XOFF FQs will remain in the tenatively-scheduled state, even when
+ * non-empty, meaning they won't be selected for scheduled dequeuing. If a FQ is
+ * changed to XOFF after it had already become truly-scheduled to a channel, and
+ * a pull dequeue of that channel occurs that selects that FQ for dequeuing,
+ * then the resulting dq_entry will have no FD. (qbman_result_DQ_fd() will
+ * return NULL.)
+ */
+/**
+ * qbman_swp_fq_xon() - XON the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid);
+/**
+ * qbman_swp_fq_xoff() - XOFF the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid);
+
+ /**********************/
+ /* Channel management */
+ /**********************/
+
+/**
+ * If the user has been allocated a channel object that is going to generate
+ * CDANs to another channel, then these functions will be necessary.
+ * CDAN-enabled channels only generate a single CDAN notification, after which
+ * it they need to be reenabled before they'll generate another. (The idea is
+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
+ * reenable step.) Each function generates a distinct command to hardware, so a
+ * combination function is provided if the user wishes to modify the "context"
+ * (which shows up in each CDAN message) each time they reenable, as a single
+ * command to hardware.
+ */
+
+/**
+ * qbman_swp_CDAN_set_context() - Set CDAN context
+ * @s: the software portal object.
+ * @channelid: the channel index.
+ * @ctx: the context to be set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+
+/**
+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_disable() - disable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ * @ctx: the context set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ uint8_t burst_index);
+int qbman_swp_flush_ring(struct qbman_swp *s);
+void qbman_sync(void);
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send);
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+int qbman_get_version(void);
+#endif /* !_FSL_QBMAN_PORTAL_H */
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
new file mode 100644
index 0000000..11116bd
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.c
@@ -0,0 +1,1495 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQCR_PI 0x800
+#define QBMAN_CINH_SWP_EQCR_CI 0x840
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DQPI 0xa00
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+#define QBMAN_CINH_SWP_ISR 0xe00
+#define QBMAN_CINH_SWP_IER 0xe40
+#define QBMAN_CINH_SWP_ISDR 0xe80
+#define QBMAN_CINH_SWP_IIR 0xec0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+#define QBMAN_CENA_SWP_EQCR_CI 0x840
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
+
+/* QBMan FQ management command codes */
+#define QBMAN_FQ_SCHEDULE 0x48
+#define QBMAN_FQ_FORCE 0x49
+#define QBMAN_FQ_XON 0x4d
+#define QBMAN_FQ_XOFF 0x4e
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init()
+ */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_eq_dca_idx;
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+struct qb_attr_code code_sdqcr_dqsrc = QB_CODE(0, 0, 16);
+
+/* We need to keep track of which SWP triggered a pull command
+ * so keep an array of portal IDs and use the token field to
+ * be able to find the proper portal
+ */
+#define MAX_QBMAN_PORTALS 35
+static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
+
+uint32_t qman_version;
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has.
+ *
+ * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
+ * valid-bits, so we need to support a workaround where we don't trust
+ * valid-bits when detecting new entries until any stale ring entries have been
+ * overwritten at least once. The idea is that we read PI for the first few
+ * entries, then switch to valid-bit after that. The trick is to clear the
+ * bug-work-around boolean once the PI wraps around the ring for the first time.
+ *
+ * Note: this still carries a slight additional cost once the decrementer hits
+ * zero.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ uint32_t eqcr_pi;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = *d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
+ atomic_set(&p->vdq.busy, 1);
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ qman_version = p->desc.qman_version;
+ if ((qman_version & 0xFFFF0000) < QMAN_REV_4100) {
+ p->dqrr.dqrr_size = 4;
+ p->dqrr.reset_bug = 1;
+ /* Set size of DQRR to 4, encoded in 2 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 2);
+ } else {
+ p->dqrr.dqrr_size = 8;
+ p->dqrr.reset_bug = 0;
+ /* Set size of DQRR to 8, encoded in 3 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 3);
+ }
+
+ ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
+ if (ret) {
+ kfree(p);
+ pr_err("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ /* SDQCR needs to be initialized to 0 when no channels are
+ * being dequeued from or else the QMan HW will indicate an
+ * error. The values that were calculated above will be
+ * applied when dequeues from a specific channel are enabled
+ */
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
+ eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
+ p->eqcr.pi = eqcr_pi & 0xF;
+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
+ p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & 0xF;
+ p->eqcr.available = QBMAN_EQCR_SIZE - qm_cyc_diff(QBMAN_EQCR_SIZE,
+ p->eqcr.ci, p->eqcr.pi);
+
+ portal_idx_map[p->desc.idx] = p;
+ return p;
+}
+
+void qbman_swp_finish(struct qbman_swp *p)
+{
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ qbman_swp_sys_finish(&p->sys);
+ portal_idx_map[p->desc.idx] = NULL;
+ kfree(p);
+}
+
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
+{
+ return &p->desc;
+}
+
+/**************/
+/* Interrupts */
+/**************/
+
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
+}
+
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
+}
+
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
+}
+
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
+}
+
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
+}
+
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
+}
+
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
+}
+
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
+#endif
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so.
+ */
+ QBMAN_BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ qbman_cena_invalidate_prefetch(&p->sys,
+ QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_eqdi = QB_CODE(0, 3, 1);
+static struct qb_attr_code code_eq_dca_en = QB_CODE(0, 15, 1);
+static struct qb_attr_code code_eq_dca_pk = QB_CODE(0, 14, 1);
+/* Can't set code_eq_dca_idx width. Need qman version. Read at runtime */
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_orp_is_nesn = QB_CODE(0, 31, 1);
+static struct qb_attr_code code_eq_orp_nlis = QB_CODE(0, 30, 1);
+static struct qb_attr_code code_eq_orp_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_eq_opr_id = QB_CODE(1, 0, 16);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
+static struct qb_attr_code code_eq_rsp_id = QB_CODE(5, 24, 8);
+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
+
+enum qbman_eq_cmd_e {
+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, !!incomplete);
+}
+
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 0);
+}
+
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 1);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
+}
+
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_rsp_id, cl, (uint32_t)token);
+}
+
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 0);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, fqid);
+}
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_eqdi, cl, !!enable);
+}
+
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_dca_en, cl, !!enable);
+ if (enable) {
+ qb_attr_code_encode(&code_eq_dca_pk, cl, !!park);
+ qb_attr_code_encode(&code_eq_dca_idx, cl, dqrr_idx);
+ }
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+
+ pr_debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ return 0;
+}
+
+static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ return 0;
+}
+
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ __attribute__((unused)) uint8_t burst_index)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR((s->eqcr.pi/* +burst_index */) & 7));
+ /* word_copy(&p[1], &cl[1], 7); */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ /* word_copy(&p[8], fd, sizeof(*fd) >> 2); */
+ memcpy(&p[8], fd, sizeof(struct qbman_fd));
+
+ /* lwsync(); */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+
+ return 0;
+}
+
+int qbman_swp_flush_ring(struct qbman_swp *s)
+{
+ void *ptr = s->sys.addr_cena;
+
+ dcbf((uint64_t)ptr);
+ dcbf((uint64_t)ptr + 0x40);
+ dcbf((uint64_t)ptr + 0x80);
+ dcbf((uint64_t)ptr + 0xc0);
+ dcbf((uint64_t)ptr + 0x100);
+ dcbf((uint64_t)ptr + 0x140);
+ dcbf((uint64_t)ptr + 0x180);
+ dcbf((uint64_t)ptr + 0x1c0);
+
+ return 0;
+}
+
+void qbman_sync(void)
+{
+ lwsync();
+}
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ if (s->sys.eqcr_mode == qman_eqcr_vb_array)
+ return qbman_swp_enqueue_array_mode(s, d, fd);
+ else /* Use ring mode by default */
+ return qbman_swp_enqueue_ring_mode(s, d, fd);
+}
+
+/*************************/
+/* Static (push) dequeue */
+/*************************/
+
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
+{
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ *enabled = (int)qb_attr_code_decode(&code, &s->sdq);
+}
+
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
+{
+ uint16_t dqsrc;
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ qb_attr_code_encode(&code, &s->sdq, !!enable);
+ /* Read make the complete src map. If no channels are enabled
+ * the SDQCR must be 0 or else QMan will assert errors
+ */
+ dqsrc = (uint16_t)qb_attr_code_decode(&code_sdqcr_dqsrc, &s->sdq);
+ if (dqsrc != 0)
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
+ else
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
+
+enum qb_pull_dt_e {
+ qb_pull_dt_channel,
+ qb_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command)
+ */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ qb_attr_code_encode(&code_pull_rls, cl, 1);
+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ QBMAN_BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_workqueue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, wqid);
+}
+
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_channel);
+ qb_attr_code_encode(&code_pull_dqsource, cl, chid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
+ return -EBUSY;
+ }
+ s->vdq.storage = *(void **)&cl[4];
+ /* We use portal index +1 as token so that 0 still indicates
+ * that the result isn't valid yet.
+ */
+ qb_attr_code_encode(&code_pull_token, cl, s->desc.idx + 1);
+ p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ word_copy(&p[1], &cl[1], 3);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+static struct qb_attr_code code_dqrr_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_dqrr_odpid = QB_CODE(1, 0, 16);
+/* static struct qb_attr_code code_dqrr_tok = QB_CODE(1, 24, 8); */
+static struct qb_attr_code code_dqrr_fqid = QB_CODE(2, 0, 24);
+static struct qb_attr_code code_dqrr_byte_count = QB_CODE(4, 0, 32);
+static struct qb_attr_code code_dqrr_frame_count = QB_CODE(5, 0, 24);
+static struct qb_attr_code code_dqrr_ctx_lo = QB_CODE(6, 0, 32);
+
+#define QBMAN_RESULT_DQ 0x60
+#define QBMAN_RESULT_FQRN 0x21
+#define QBMAN_RESULT_FQRNI 0x22
+#define QBMAN_RESULT_FQPN 0x24
+#define QBMAN_RESULT_FQDAN 0x25
+#define QBMAN_RESULT_CDAN 0x26
+#define QBMAN_RESULT_CSCN_MEM 0x27
+#define QBMAN_RESULT_CGCU 0x28
+#define QBMAN_RESULT_BPSCN 0x29
+#define QBMAN_RESULT_CSCN_WQ 0x2a
+
+static struct qb_attr_code code_dqpi_pi = QB_CODE(0, 0, 4);
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ uint32_t verb;
+ uint32_t response_verb;
+ uint32_t flags;
+ const struct qbman_result *dq;
+ const uint32_t *p;
+
+ /* Before using valid-bit to detect if something is there, we have to
+ * handle the case of the DQRR reset bug...
+ */
+ if (unlikely(s->dqrr.reset_bug)) {
+ /* We pick up new entries by cache-inhibited producer index,
+ * which means that a non-coherent mapping would require us to
+ * invalidate and read *only* once that PI has indicated that
+ * there's an entry here. The first trip around the DQRR ring
+ * will be much less efficient than all subsequent trips around
+ * it...
+ */
+ uint32_t dqpi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI);
+ uint32_t pi = qb_attr_code_decode(&code_dqpi_pi, &dqpi);
+ /* there are new entries iff pi != next_idx */
+ if (pi == s->dqrr.next_idx)
+ return NULL;
+ /* if next_idx is/was the last ring index, and 'pi' is
+ * different, we can disable the workaround as all the ring
+ * entries have now been DMA'd to so valid-bit checking is
+ * repaired. Note: this logic needs to be based on next_idx
+ * (which increments one at a time), rather than on pi (which
+ * can burst and wrap-around between our snapshots of it).
+ */
+ QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
+ pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
+ s->dqrr.next_idx, pi);
+ s->dqrr.reset_bug = 0;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ }
+ dq = qbman_cena_read_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
+ return NULL;
+
+ /* There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found.
+ */
+ s->dqrr.next_idx++;
+ if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
+ s->dqrr.next_idx = 0;
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+ }
+ /* If this is the final response to a volatile dequeue command
+ * indicate that the vdq is no longer busy.
+ */
+ flags = qbman_result_DQ_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_RESULT_DQ) &&
+ (flags & QBMAN_DQ_STAT_VOLATILE) &&
+ (flags & QBMAN_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+int qbman_result_has_new_result(__attribute__((unused)) struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* Entry is valid - overwrite token back to 0 so
+ * a) If this memory is reused tokesn will be 0
+ * b) If someone calls "has_new_result()" again on this entry it
+ * will not appear to be new
+ */
+ qb_attr_code_encode(&code_dqrr_tok_detect, &p[1], 0);
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice...
+ */
+ make_le32_n(p, 16);
+ return 1;
+}
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* TODO: Remove qbman_swp from parameters and make it a local
+ * once we've tested the reserve portal map change
+ */
+ s = portal_idx_map[token - 1];
+ /* When token is set it indicates that VDQ command has been fetched
+ * by qbman and is working on it. It is safe for software to issue
+ * another VDQ command, so incrementing the busy variable.
+ */
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
+ return 1;
+}
+
+/********************************/
+/* Categorising qbman results */
+/********************************/
+
+static struct qb_attr_code code_result_in_mem =
+ QB_CODE(0, QBMAN_RESULT_VERB_OFFSET_IN_MEM, 7);
+
+static inline int __qbman_result_is_x(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return (response_verb == x);
+}
+
+static inline int __qbman_result_is_x_in_mem(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_result_in_mem, p);
+
+ return (response_verb == x);
+}
+
+int qbman_result_is_DQ(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
+}
+
+int qbman_result_is_FQDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
+}
+
+int qbman_result_is_CDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
+}
+
+int qbman_result_is_CSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CSCN_MEM) ||
+ __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
+}
+
+int qbman_result_is_BPSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_BPSCN);
+}
+
+int qbman_result_is_CGCU(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CGCU);
+}
+
+int qbman_result_is_FQRN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRN);
+}
+
+int qbman_result_is_FQRNI(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRNI);
+}
+
+int qbman_result_is_FQPN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_result_is_DQ() is TRUE */
+
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_seqnum, p);
+}
+
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_odpid, p);
+}
+
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_fqid, p);
+}
+
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_byte_count, p);
+}
+
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_frame_count, p);
+}
+
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(dq);
+
+ return qb_attr_code_decode_64(&code_dqrr_ctx_lo, p);
+}
+
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct qbman_fd *)&p[8];
+}
+
+/**************************************/
+/* Parsing state-change notifications */
+/**************************************/
+
+static struct qb_attr_code code_scn_state = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_scn_rid = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_scn_state_in_mem =
+ QB_CODE(0, SCN_STATE_OFFSET_IN_MEM, 8);
+static struct qb_attr_code code_scn_rid_in_mem =
+ QB_CODE(1, SCN_RID_OFFSET_IN_MEM, 24);
+static struct qb_attr_code code_scn_ctx_lo = QB_CODE(2, 0, 32);
+
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state, p);
+}
+
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return qb_attr_code_decode(&code_scn_rid, p);
+}
+
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(scn);
+
+ return qb_attr_code_decode_64(&code_scn_ctx_lo, p);
+}
+
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state_in_mem, p);
+}
+
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+ uint32_t result_rid;
+
+ result_rid = qb_attr_code_decode(&code_scn_rid_in_mem, p);
+ return make_le24(result_rid);
+}
+
+/*****************/
+/* Parsing BPSCN */
+/*****************/
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0x3FFF;
+}
+
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
+{
+ return !(int)(qbman_result_SCN_state_in_mem(scn) & 0x1);
+}
+
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x2);
+}
+
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x4);
+}
+
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)make_le32(ctx_hi) << 32 |
+ (uint64_t)make_le32(ctx_lo));
+}
+
+/*****************/
+/* Parsing CGCU */
+/*****************/
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0xFFFF;
+}
+
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)(make_le32(ctx_hi) & 0xFF) << 32) |
+ (uint64_t)make_le32(ctx_lo);
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_rcdi = QB_CODE(0, 6, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_rcdi, cl, !!enable);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+
+ pr_debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers.
+ */
+ lwsync();
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t rslt, num;
+
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ QBMAN_BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
+
+/*****************/
+/* FQ management */
+/*****************/
+
+static struct qb_attr_code code_fqalt_fqid = QB_CODE(1, 0, 32);
+
+static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
+ uint8_t alt_fq_verb)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ qb_attr_code_encode(&code_fqalt_fqid, p, fqid);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | alt_fq_verb);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != alt_fq_verb);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
+ fqid, alt_fq_verb, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
+}
+
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
+}
+
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
+}
+
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
+}
+
+/**********************/
+/* Channel management */
+/**********************/
+
+static struct qb_attr_code code_cdan_cid = QB_CODE(0, 16, 12);
+static struct qb_attr_code code_cdan_we = QB_CODE(1, 0, 8);
+static struct qb_attr_code code_cdan_en = QB_CODE(1, 8, 1);
+static struct qb_attr_code code_cdan_ctx_lo = QB_CODE(2, 0, 32);
+
+/* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
+ * would be irresponsible to expose it.
+ */
+#define CODE_CDAN_WE_EN 0x1
+#define CODE_CDAN_WE_CTX 0x4
+
+static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
+ uint8_t we_mask, uint8_t cdan_en,
+ uint64_t ctx)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_cdan_cid, p, channelid);
+ qb_attr_code_encode(&code_cdan_we, p, we_mask);
+ qb_attr_code_encode(&code_cdan_en, p, cdan_en);
+ qb_attr_code_encode_64(&code_cdan_ctx_lo, (uint64_t *)p, ctx);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_WQCHAN_CONFIGURE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p)
+ != QBMAN_WQCHAN_CONFIGURE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("CDAN cQID %d failed: code = 0x%02x\n",
+ channelid, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_CTX,
+ 0, ctx);
+}
+
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 1, 0);
+}
+
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 0, 0);
+}
+
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
+ 1, ctx);
+}
+
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr)
+{
+ return QBMAN_IDX_FROM_DQRR(dqrr);
+}
+
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
+{
+ struct qbman_result *dq;
+
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
+ return dq;
+}
+
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+ int sent = 0;
+ int i;
+ int initial_pi = s->eqcr.pi;
+ uint64_t start_pointer;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ if (!diff)
+ goto done;
+ s->eqcr.available += diff;
+ }
+
+ /* we are trying to send frames_to_send,
+ * if we have enough space in the ring
+ */
+ while (s->eqcr.available && frames_to_send--) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+ /* Write command (except of first byte) and FD */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ memcpy(&p[8], &fd[sent], sizeof(struct qbman_fd));
+
+ initial_pi++;
+ initial_pi &= 0xF;
+ s->eqcr.available--;
+ sent++;
+ }
+
+done:
+ initial_pi = s->eqcr.pi;
+ lwsync();
+
+ /* in order for flushes to complete faster:
+ * we use a following trick: we record all lines in 32 bit word
+ */
+
+ initial_pi = s->eqcr.pi;
+ for (i = 0; i < sent; i++) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ initial_pi++;
+ initial_pi &= 0xF;
+
+ if (!(initial_pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ initial_pi = s->eqcr.pi;
+
+ /* We need to flush all the lines but without
+ * load/store operations between them.
+ * We assign start_pointer before we start loop so that
+ * in loop we do not read it from memory
+ */
+ start_pointer = (uint64_t)s->sys.addr_cena;
+ for (i = 0; i < sent; i++) {
+ p = (uint32_t *)(start_pointer
+ + QBMAN_CENA_SWP_EQCR(initial_pi & 7));
+ dcbf((uint64_t)p);
+ initial_pi++;
+ initial_pi &= 0xF;
+ }
+
+ /* Update producer index for the next call */
+ s->eqcr.pi = initial_pi;
+
+ return sent;
+}
+
+int qbman_get_version(void)
+{
+ return qman_version;
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.h b/drivers/common/dpaa2/qbman/qbman_portal.h
new file mode 100644
index 0000000..7aa1d4f
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.h
@@ -0,0 +1,277 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_private.h"
+#include <fsl_qbman_portal.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* QBMan DQRR size is set at runtime in qbman_portal.c */
+
+#define QBMAN_EQCR_SIZE 8
+
+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return last - first;
+ return (2 * ringsize) + last - first;
+}
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ struct qbman_swp_desc desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here.
+ */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * to whether or not a command can be submitted, not whether or
+ * not a previously-submitted command is still executing. In
+ * other words, once proof is seen that the previously-submitted
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ /* We need to determine when vdq is no longer busy. This depends
+ * on whether the "busy" (last-submitted) dequeue command is
+ * targeting DQRR or main-memory, and detected is based on the
+ * presence of the dequeue command's "token" showing up in
+ * dequeue entries in DQRR or main-memory (respectively).
+ */
+ struct qbman_result *storage; /* NULL if DQRR */
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ uint8_t dqrr_size;
+ int reset_bug;
+ } dqrr;
+ struct {
+ uint32_t pi;
+ uint32_t pi_vb;
+ uint32_t ci;
+ int available;
+ } eqcr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete).
+ */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and DPAA2 QBMan is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Some pre-defined codes */
+extern struct qb_attr_code code_generic_verb;
+extern struct qb_attr_code code_generic_rslt;
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+#define QB_CODE_NULL \
+ QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
+
+/* Rotate a code "ms", meaning that it moves from less-significant bytes to
+ * more-significant, from less-significant words to more-significant, etc. The
+ * "ls" version does the inverse, from more-significant towards
+ * less-significant.
+ */
+static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ code->lsoffset += bits;
+ while (code->lsoffset > 31) {
+ code->word++;
+ code->lsoffset -= 32;
+ }
+}
+
+static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ /* Don't be fooled, this trick should work because the types are
+ * unsigned. So the case that interests the while loop (the rotate has
+ * gone too far and the word count needs to compensate for it), is
+ * manifested when lsoffset is negative. But that equates to a really
+ * large unsigned value, starting with lots of "F"s. As such, we can
+ * continue adding 32 back to it until it wraps back round above zero,
+ * to a value of 31 or less...
+ */
+ code->lsoffset -= bits;
+ while (code->lsoffset > 31) {
+ code->word--;
+ code->lsoffset += 32;
+ }
+}
+
+/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
+#define qb_attr_code_for_ms(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ms(code, bits))
+#define qb_attr_code_for_ls(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ls(code, bits))
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
+}
+
+static inline uint64_t qb_attr_code_decode_64(const struct qb_attr_code *code,
+ const uint64_t *cacheline)
+{
+ return cacheline[code->word / 2];
+}
+
+/* encode a field to a cacheline */
+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
+ uint32_t *cacheline, uint32_t val)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
+/* Small-width signed values (two's-complement) will decode into medium-width
+ * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
+ * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
+ * 249. Likewise -120 would decode as 136.) This function allows the caller to
+ * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
+ * encoding, will become 0xfffffff9 if you cast the return value to uint32_t).
+ */
+static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
+ uint32_t val)
+{
+ QBMAN_BUG_ON(val >= (1u << code->width));
+ /* code->width should never exceed the width of val. If it does then a
+ * different function with larger val size must be used to translate
+ * from unsigned to signed
+ */
+ QBMAN_BUG_ON(code->width > sizeof(val) * CHAR_BIT);
+ /* If the high bit was set, it was encoding a negative */
+ if (val >= 1u << (code->width - 1))
+ return (int32_t)0 - (int32_t)(((uint32_t)1 << code->width) -
+ val);
+ /* Otherwise, it was encoding a positive */
+ return (int32_t)val;
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * a "descriptor" type that the caller can instantiate however they like.
+ * Ultimately though, it is just a cacheline of binary storage (or something
+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
+ * holding pre-formatted pieces of hardware commands. The performance-critical
+ * code can then copy these descriptors directly into hardware command
+ * registers more efficiently than trying to construct/format commands
+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/common/dpaa2/qbman/qbman_private.h b/drivers/common/dpaa2/qbman/qbman_private.h
new file mode 100644
index 0000000..f5fa13d
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_private.h
@@ -0,0 +1,170 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+/* Perform extra checking */
+#define QBMAN_CHECKING
+
+/* To maximise the amount of logic that is common between the Linux driver and
+ * other targets (such as the embedded MC firmware), we pivot here between the
+ * inclusion of two platform-specific headers.
+ *
+ * The first, qbman_sys_decl.h, includes any and all required system headers as
+ * well as providing any definitions for the purposes of compatibility. The
+ * second, qbman_sys.h, is where platform-specific routines go.
+ *
+ * The point of the split is that the platform-independent code (including this
+ * header) may depend on platform-specific declarations, yet other
+ * platform-specific routines may depend on platform-independent definitions.
+ */
+
+#include "qbman_sys_decl.h"
+
+/* When things go wrong, it is a convenient trick to insert a few FOO()
+ * statements in the code to trace progress. TODO: remove this once we are
+ * hacking the code less actively.
+ */
+#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+do { \
+ if (!(loopvar--)) \
+ QBMAN_BUG_ON(NULL == "DBG_POLL_CHECK"); \
+} while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ pr_info("%s", buf);
+ }
+}
+
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#include "qbman_sys.h"
diff --git a/drivers/common/dpaa2/qbman/qbman_sys.h b/drivers/common/dpaa2/qbman/qbman_sys.h
new file mode 100644
index 0000000..5dbcaa5
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys.h
@@ -0,0 +1,385 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required.
+ */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness.
+ */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+
+static inline uint32_t make_le24(uint32_t val)
+{
+ return (((val & 0xff) << 16) | (val & 0xff00) |
+ ((val & 0xff0000) >> 16));
+}
+
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+#else
+#define make_le32(val) (val)
+#define make_le24(val) (val)
+#define make_le32_n(val, len) do {} while (0)
+#endif
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder.
+ */
+ uint8_t *cena;
+ uint8_t __iomem *addr_cena;
+ uint8_t __iomem *addr_cinh;
+ uint32_t idx;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void *qbman_cena_write_start_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 1; loop--)
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+ lwsync();
+ __raw_writel(shadow[0], s->addr_cena + offset);
+ dcbf(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+ hexdump(cmd, 64);
+#endif
+ dcbf(s->addr_cena + offset);
+}
+
+static inline uint32_t qbman_cena_read_reg(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ return __raw_readl(s->addr_cena + offset);
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = (uint32_t *)(s->cena + offset);
+ unsigned int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void *qbman_cena_read_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return s->addr_cena + offset;
+}
+
+static inline void qbman_cena_invalidate(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here.
+ */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x2)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x2)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- TRUE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- TRUE)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- TRUE)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- TRUE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) |
+ e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d,
+ uint8_t dqrr_size)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->idx = (uint32_t)d->idx;
+ s->cena = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!s->cena) {
+ pr_err("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+ s->eqcr_mode = d->eqcr_mode;
+ QBMAN_BUG_ON(d->idx < 0);
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ QBMAN_BUG_ON(reg);
+#endif
+ if (s->eqcr_mode == qman_eqcr_vb_array)
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 1, 1, 1, 1,
+ 1, 1);
+ else
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 2, 3, 2, 2, 1, 1, 1, 1,
+ 1, 1);
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ pr_err("The portal %d is not enabled!\n", s->idx);
+ kfree(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free_page((unsigned long)s->cena);
+}
+
+static inline void *
+qbman_cena_write_start_wo_shadow_fast(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_sys_decl.h b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
new file mode 100644
index 0000000..e52f5ed
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
@@ -0,0 +1,73 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 <compat.h>
+#include <fsl_qbman_base.h>
+
+/* Sanity check */
+#if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && \
+ (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
+#error "Unknown endianness!"
+#endif
+
+/* The platform-independent code shouldn't need endianness, except for
+ * weird/fast-path cases like qbman_result_has_token(), which needs to
+ * perform a passive and endianness-specific test on a read-only data structure
+ * very quickly. It's an exception, and this symbol is used for that case.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define DQRR_TOK_OFFSET 0
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 24
+#define SCN_STATE_OFFSET_IN_MEM 8
+#define SCN_RID_OFFSET_IN_MEM 8
+#else
+#define DQRR_TOK_OFFSET 24
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 0
+#define SCN_STATE_OFFSET_IN_MEM 16
+#define SCN_RID_OFFSET_IN_MEM 0
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
+#define lwsync() { asm volatile("dmb st" : : : "memory"); }
+#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); }
+#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); }
+static inline void prefetch_for_load(void *p)
+{
+ asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p));
+}
+
+static inline void prefetch_for_store(void *p)
+{
+ asm volatile("prfm pstl1keep, [%0, #64]" : : "r" (p));
+}
diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
new file mode 100644
index 0000000..f653421
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
@@ -0,0 +1,27 @@
+DPDK_17.02 {
+ global:
+
+ qbman_check_command_complete;
+ qbman_eq_desc_clear;
+ qbman_eq_desc_set_fq;
+ qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_qd;
+ qbman_eq_desc_set_response;
+ qbman_get_version;
+ qbman_pull_desc_clear;
+ qbman_pull_desc_set_fq;
+ qbman_pull_desc_set_numframes;
+ qbman_pull_desc_set_storage;
+ qbman_release_desc_clear;
+ qbman_release_desc_set_bpid;
+ qbman_result_DQ_fd;
+ qbman_result_DQ_flags;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
+ qbman_swp_init;
+ qbman_swp_pull;
+ qbman_swp_release;
+ qbman_swp_send_multiple;
+
+ local: *;
+};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-01-23 17:30 ` Ferruh Yigit
2017-01-24 6:28 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:30 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Geoff Thorpe, Roy Pledge
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> QBMAN, is a hardware block which interfaces with the other
> accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
> SoC for queue, buffer and packet scheduling.
>
> This patch introduces a userspace driver for interfacing with
> the QBMAN hw block.
>
> The qbman-portal component provides APIs to do the low level
> hardware bit twiddling for operations such as:
> -initializing Qman software portals
> -building and sending portal commands
> -portal interrupt configuration and processing
>
> This same/similar code is used in kernel and compat file is used
> to make it working in user space.
>
> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
> Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> --- a/config/common_base
> +++ b/config/common_base
> @@ -287,7 +287,6 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
> CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
> CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
>
> -#
Minor typo ..
> # Compile burst-oriented VIRTIO PMD driver
> #
> CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
<...>
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> @@ -0,0 +1,27 @@
> +DPDK_17.02 {
> + global:
> +
> + qbman_check_command_complete;
> + qbman_eq_desc_clear;
> + qbman_eq_desc_set_fq;
> + qbman_eq_desc_set_no_orp;
> + qbman_eq_desc_set_qd;
> + qbman_eq_desc_set_response;
> + qbman_get_version;
> + qbman_pull_desc_clear;
> + qbman_pull_desc_set_fq;
> + qbman_pull_desc_set_numframes;
> + qbman_pull_desc_set_storage;
> + qbman_release_desc_clear;
> + qbman_release_desc_set_bpid;
> + qbman_result_DQ_fd;
> + qbman_result_DQ_flags;
> + qbman_result_has_new_result;
> + qbman_swp_acquire;
> + qbman_swp_init;
> + qbman_swp_pull;
> + qbman_swp_release;
> + qbman_swp_send_multiple;
Overall, dpdk library exported APIs not having DPDK prefix (rte_) is a
concern, which already pointed by Thomas.
I guess only user of this library will be other dpaa2 code, so these are
not really APIs. Not sure how to proceed.
I think I have seen "_rte" prefix used in some APIs to say that is
internal API, does it make sense to use that API here?
> +
> + local: *;
> +};
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver
2017-01-23 17:30 ` Ferruh Yigit
@ 2017-01-24 6:28 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-24 6:28 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Hemant Agrawal, dev, thomas.monjalon, bruce.richardson,
john.mcnamara, jerin.jacob, Geoff Thorpe, Roy Pledge
Hello Ferruh,
On Monday 23 January 2017 11:00 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> QBMAN, is a hardware block which interfaces with the other
>> accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
>> SoC for queue, buffer and packet scheduling.
>>
>> This patch introduces a userspace driver for interfacing with
>> the QBMAN hw block.
>>
>> The qbman-portal component provides APIs to do the low level
>> hardware bit twiddling for operations such as:
>> -initializing Qman software portals
>> -building and sending portal commands
>> -portal interrupt configuration and processing
>>
>> This same/similar code is used in kernel and compat file is used
>> to make it working in user space.
>>
>> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
>> Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
> <...>
>
>> --- a/config/common_base
>> +++ b/config/common_base
>> @@ -287,7 +287,6 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
>> CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
>> CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
>>
>> -#
Ah, yes, stray removal. We will remove it.
(Thanks for review - really appreciate your help).
>
> Minor typo ..
>
>> # Compile burst-oriented VIRTIO PMD driver
>> #
>> CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
>
> <...>
>
>> --- /dev/null
>> +++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
>> @@ -0,0 +1,27 @@
>> +DPDK_17.02 {
>> + global:
>> +
>> + qbman_check_command_complete;
>> + qbman_eq_desc_clear;
>> + qbman_eq_desc_set_fq;
>> + qbman_eq_desc_set_no_orp;
>> + qbman_eq_desc_set_qd;
>> + qbman_eq_desc_set_response;
>> + qbman_get_version;
>> + qbman_pull_desc_clear;
>> + qbman_pull_desc_set_fq;
>> + qbman_pull_desc_set_numframes;
>> + qbman_pull_desc_set_storage;
>> + qbman_release_desc_clear;
>> + qbman_release_desc_set_bpid;
>> + qbman_result_DQ_fd;
>> + qbman_result_DQ_flags;
>> + qbman_result_has_new_result;
>> + qbman_swp_acquire;
>> + qbman_swp_init;
>> + qbman_swp_pull;
>> + qbman_swp_release;
>> + qbman_swp_send_multiple;
>
> Overall, dpdk library exported APIs not having DPDK prefix (rte_) is a
> concern, which already pointed by Thomas.
>
> I guess only user of this library will be other dpaa2 code, so these are
> not really APIs. Not sure how to proceed.
> I think I have seen "_rte" prefix used in some APIs to say that is
> internal API, does it make sense to use that API here?
We had a detailed discussion on this internally after Thomas' comments.
It is very difficult to convert all such symbols - primarily because it
will break the 'linkage' between our Linux upstream candidate code,
internal repositories and what we are pushing to DPDK.
This is happening because we are spreading our common libraries beyond
the drivers/net/* scope. If we combine all of them together (no
drivers/common, drivers/pool etc), these symbols would not be exposed.
There was a discussion on ML as well for this kind of structure on our
first RFC submission.
We were in favor of a split design because that makes the overall PMD
look clean. But, this rte_* prefix issue is something we never
anticipated.
Further, we took hint from existing map files which also had similar
non rte_* symbols (per_lcore_*, devargs_list, pci_device_list etc) to
convince ourselves that this is not a strict rule.
As for "_rte" - once again, we need to define what internal is when it
comes to drivers/common, drivers/bus, drivers/pool .. kind of code
layout having functionality divided. It might be internal to framework
(limited to drivers/*) but would be external for a drivers/net/*.
Overall, a serious discussion on this is indeed needed for clarity as
more non-PCI drivers might contributed in near future with basic bus
infra in place.
>
>> +
>> + local: *;
>> +};
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 03/33] bus/fslmc: introducing fsl-mc bus driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 01/33] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 02/33] drivers/common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 04/33] bus/fslmc: introduce mc object functions Hemant Agrawal
` (32 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
for NXP DPAA2 SoCs.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/Makefile | 1 +
drivers/bus/Makefile | 36 +++++++
drivers/bus/fslmc/Makefile | 52 ++++++++++
drivers/bus/fslmc/fslmc_bus.c | 125 +++++++++++++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 7 ++
drivers/bus/fslmc/rte_fslmc.h | 148 ++++++++++++++++++++++++++++
drivers/common/Makefile | 4 +
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
12 files changed, 392 insertions(+)
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ad150d..4a13140 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -356,6 +356,7 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
QLogic bnx2x
diff --git a/config/common_base b/config/common_base
index 5564d92..bf1de8f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,6 +287,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=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 da23bab..365ae5a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -41,3 +41,8 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
#
CONFIG_RTE_MAX_LCORE=8
CONFIG_RTE_MAX_NUMA_NODES=1
+
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=y
diff --git a/drivers/Makefile b/drivers/Makefile
index d5580f6..bdae63b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -32,6 +32,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
+DIRS-y += bus
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000..60e9764
--- /dev/null
+++ b/drivers/bus/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_FSLMC_BUS) += fslmc
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
new file mode 100644
index 0000000..5a0fd61
--- /dev/null
+++ b/drivers/bus/fslmc/Makefile
@@ -0,0 +1,52 @@
+# 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_fslmc.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_fslmc_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
new file mode 100644
index 0000000..8a4f519
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -0,0 +1,125 @@
+/*-
+ * 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.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_ethdev.h>
+
+#include "rte_fslmc.h"
+
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+ RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+struct rte_fslmc_bus rte_fslmc_bus;
+
+static int
+rte_fslmc_scan(void)
+{
+ return 0;
+}
+
+static int
+rte_fslmc_match(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
+ return 0;
+
+ return 1;
+}
+
+static int
+rte_fslmc_probe(void)
+{
+ int ret = -1;
+ struct rte_dpaa2_device *dev;
+ struct rte_dpaa2_driver *drv;
+
+ TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
+ TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
+ ret = rte_fslmc_match(drv, dev);
+ if (ret)
+ continue;
+
+ if (!drv->probe)
+ continue;
+
+ ret = drv->probe(drv, dev);
+ if (ret)
+ FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
+ break;
+ }
+ }
+ return ret;
+}
+
+/*register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
+{
+ RTE_VERIFY(driver);
+
+ TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = &rte_fslmc_bus;
+}
+
+/*un-register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver)
+{
+ struct rte_fslmc_bus *fslmc_bus;
+
+ fslmc_bus = driver->fslmc_bus;
+
+ TAILQ_REMOVE(&fslmc_bus->driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = NULL;
+}
+
+struct rte_fslmc_bus rte_fslmc_bus = {
+ .bus = {
+ .scan = rte_fslmc_scan,
+ .probe = rte_fslmc_probe,
+ },
+ .device_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.device_list),
+ .driver_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus);
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
new file mode 100644
index 0000000..4d525ba
--- /dev/null
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -0,0 +1,7 @@
+DPDK_17.02 {
+ global:
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
new file mode 100644
index 0000000..040ab95
--- /dev/null
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -0,0 +1,148 @@
+/*-
+ * 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 _RTE_FSLMC_H_
+#define _RTE_FSLMC_H_
+
+/**
+ * @file
+ *
+ * RTE FSLMC Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/** Name of FSLMC Bus */
+#define FSLMC_BUS_NAME "FSLMC"
+
+struct rte_dpaa2_driver;
+
+/* DPAA2 Device and Driver lists for FSLMC bus */
+TAILQ_HEAD(rte_fslmc_device_list, rte_dpaa2_device);
+TAILQ_HEAD(rte_fslmc_driver_list, rte_dpaa2_driver);
+
+extern struct rte_fslmc_bus rte_fslmc_bus;
+
+/**
+ * A structure describing a DPAA2 device.
+ */
+struct rte_dpaa2_device {
+ TAILQ_ENTRY(rte_dpaa2_device) next; /**< Next probed DPAA2 device. */
+ struct rte_device device; /**< Inherit core device */
+ union {
+ struct rte_eth_dev *eth_dev; /**< ethernet device */
+ struct rte_cryptodev *cryptodev; /**< Crypto Device */
+ };
+ uint16_t dev_type; /**< Device Type */
+ uint16_t object_id; /**< DPAA2 Object ID */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
+ struct rte_dpaa2_driver *driver; /**< Associated driver */
+};
+
+typedef int (*rte_dpaa2_probe_t)(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev);
+typedef int (*rte_dpaa2_remove_t)(struct rte_dpaa2_device *dpaa2_dev);
+
+/**
+ * A structure describing a DPAA2 driver.
+ */
+struct rte_dpaa2_driver {
+ TAILQ_ENTRY(rte_dpaa2_driver) next; /**< Next in list. */
+ struct rte_driver driver; /**< Inherit core driver. */
+ struct rte_fslmc_bus *fslmc_bus; /**< FSLMC bus reference */
+ uint32_t drv_flags; /**< Flags for controlling device.*/
+ uint16_t drv_type; /**< Driver Type */
+ rte_dpaa2_probe_t probe;
+ rte_dpaa2_remove_t remove;
+};
+
+/*
+ * FSLMC bus
+ */
+struct rte_fslmc_bus {
+ struct rte_bus bus; /**< Generic Bus object */
+ struct rte_fslmc_device_list device_list;
+ /**< FSLMC DPAA2 Device list */
+ struct rte_fslmc_driver_list driver_list;
+ /**< FSLMC DPAA2 Driver list */
+ int device_count;
+ /**< Optional: Count of devices on bus */
+};
+
+/**
+ * Register a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be registered.
+ */
+void rte_fslmc_driver_register(struct rte_dpaa2_driver *driver);
+
+/**
+ * Unregister a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be unregistered.
+ */
+void rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver);
+
+/** Helper for DPAA2 device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_DPAA2(nm, dpaa2_drv) \
+RTE_INIT(dpaa2initfn_ ##nm); \
+static void dpaa2initfn_ ##nm(void) \
+{\
+ (dpaa2_drv).driver.name = RTE_STR(nm);\
+ rte_fslmc_driver_register(&dpaa2_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_FSLMC_H_ */
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index e5bfecb..cba1134 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),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..9681729 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
+endif
+
DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += qbman
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 5e64d23..7ac1ba7 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -36,6 +36,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_common_dpaa2_qbman.a
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
+endif
+
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 04/33] bus/fslmc: introduce mc object functions
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (2 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 03/33] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 05/33] bus/fslmc: add mc dpni object support Hemant Agrawal
` (31 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Cristian Sovaiala, Hemant Agrawal
This patch intoduces the DPAA2 MC(Management complex Driver).
This is a minimal set of low level functions to send and
receive commands to the fsl-mc. It includes support for basic
management commands and commands to manipulate MC objects.
This is common to be used by various DPAA2 PMDs. e.g.net, crypto
and other drivers.
This is a low level library also used in kernel.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 7 ++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++++++++++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 +++++++++++++++++
drivers/bus/fslmc/mc/mc_sys.c | 114 ++++++++++++++++++
4 files changed, 464 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 5a0fd61..1058f0f 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -37,6 +37,10 @@ LIB = librte_bus_fslmc.a
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += "-Wno-strict-aliasing"
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
# versioning export map
EXPORT_MAP := rte_bus_fslmc_version.map
@@ -44,6 +48,9 @@ EXPORT_MAP := rte_bus_fslmc_version.map
# library version
LIBABIVER := 1
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/mc_sys.c
+
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
new file mode 100644
index 0000000..bc41646
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
@@ -0,0 +1,238 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#define MC_CMD_NUM_OF_PARAMS 7
+
+#define MAKE_UMASK64(_width) \
+ ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : \
+ (uint64_t)-1))
+
+static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val)
+{
+ return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+
+static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width)
+{
+ return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+struct mc_command {
+ uint64_t header;
+ uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+/**
+ * enum mc_cmd_status - indicates MC status at command response
+ * @MC_CMD_STATUS_OK: Completed successfully
+ * @MC_CMD_STATUS_READY: Ready to be processed
+ * @MC_CMD_STATUS_AUTH_ERR: Authentication error
+ * @MC_CMD_STATUS_NO_PRIVILEGE: No privilege
+ * @MC_CMD_STATUS_DMA_ERR: DMA or I/O error
+ * @MC_CMD_STATUS_CONFIG_ERR: Configuration error
+ * @MC_CMD_STATUS_TIMEOUT: Operation timed out
+ * @MC_CMD_STATUS_NO_RESOURCE: No resources
+ * @MC_CMD_STATUS_NO_MEMORY: No memory available
+ * @MC_CMD_STATUS_BUSY: Device is busy
+ * @MC_CMD_STATUS_UNSUPPORTED_OP: Unsupported operation
+ * @MC_CMD_STATUS_INVALID_STATE: Invalid state
+ */
+enum mc_cmd_status {
+ MC_CMD_STATUS_OK = 0x0,
+ MC_CMD_STATUS_READY = 0x1,
+ MC_CMD_STATUS_AUTH_ERR = 0x3,
+ MC_CMD_STATUS_NO_PRIVILEGE = 0x4,
+ MC_CMD_STATUS_DMA_ERR = 0x5,
+ MC_CMD_STATUS_CONFIG_ERR = 0x6,
+ MC_CMD_STATUS_TIMEOUT = 0x7,
+ MC_CMD_STATUS_NO_RESOURCE = 0x8,
+ MC_CMD_STATUS_NO_MEMORY = 0x9,
+ MC_CMD_STATUS_BUSY = 0xA,
+ MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,
+ MC_CMD_STATUS_INVALID_STATE = 0xC
+};
+
+/* MC command flags */
+
+/**
+ * High priority flag
+ */
+#define MC_CMD_FLAG_PRI 0x00008000
+/**
+ * Command completion flag
+ */
+#define MC_CMD_FLAG_INTR_DIS 0x01000000
+
+/**
+ * Command ID field offset
+ */
+#define MC_CMD_HDR_CMDID_O 48
+/**
+ * Command ID field size
+ */
+#define MC_CMD_HDR_CMDID_S 16
+/**
+ * Token field offset
+ */
+#define MC_CMD_HDR_TOKEN_O 32
+/**
+ * Token field size
+ */
+#define MC_CMD_HDR_TOKEN_S 16
+/**
+ * Status field offset
+ */
+#define MC_CMD_HDR_STATUS_O 16
+/**
+ * Status field size
+ */
+#define MC_CMD_HDR_STATUS_S 8
+/**
+ * Flags field offset
+ */
+#define MC_CMD_HDR_FLAGS_O 0
+/**
+ * Flags field size
+ */
+#define MC_CMD_HDR_FLAGS_S 32
+/**
+ * Command flags mask
+ */
+#define MC_CMD_HDR_FLAGS_MASK 0xFF00FF00
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+ ((enum mc_cmd_status)mc_dec((_hdr), \
+ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
+
+#define MC_PREP_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= cpu_to_le64(mc_enc((_offset), (_width), _arg)))
+
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(cpu_to_le64(_ext[_param]), (_offset), (_width)))
+
+#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg))
+
+#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width)))
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ uint64_t hdr;
+
+ hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+ hdr |= mc_enc(MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S,
+ (cmd_flags & MC_CMD_HDR_FLAGS_MASK));
+ hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
+ hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+ MC_CMD_STATUS_READY);
+
+ return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+ struct mc_command *cmd)
+{
+ int i;
+ uint32_t word;
+
+ /* copy command parameters into the portal */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ iowrite64(cmd->params[i], &portal->params[i]);
+
+ /* submit the command by writing the header */
+ word = (uint32_t)mc_dec(cmd->header, 32, 32);
+ iowrite32(word, (((uint32_t *)&portal->header) + 1));
+
+ word = (uint32_t)mc_dec(cmd->header, 0, 32);
+ iowrite32(word, (uint32_t *)&portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(
+ struct mc_command __iomem *portal,
+ struct mc_command *resp)
+{
+ int i;
+ enum mc_cmd_status status;
+
+ /* Copy command response header from MC portal: */
+ resp->header = ioread64(&portal->header);
+ status = MC_CMD_HDR_READ_STATUS(resp->header);
+ if (status != MC_CMD_STATUS_OK)
+ return status;
+
+ /* Copy command response data from MC portal: */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ resp->params[i] = ioread64(&portal->params[i]);
+
+ return status;
+}
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_mc_sys.h b/drivers/bus/fslmc/mc/fsl_mc_sys.h
new file mode 100644
index 0000000..ebada60
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_sys.h
@@ -0,0 +1,105 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#ifdef __linux_driver__
+
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/slab.h>
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+
+#else /* __linux_driver__ */
+
+#include <stdio.h>
+#include <libio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <linux/byteorder/little_endian.h>
+
+#define cpu_to_le64(x) __cpu_to_le64(x)
+#ifndef dmb
+#define dmb() {__asm__ __volatile__("" : : : "memory"); }
+#endif
+#define __iormb() dmb()
+#define __iowmb() dmb()
+#define __arch_getq(a) (*(volatile unsigned long *)(a))
+#define __arch_putq(v, a) (*(volatile unsigned long *)(a) = (v))
+#define __arch_putq32(v, a) (*(volatile unsigned int *)(a) = (v))
+#define readq(c) \
+ ({ uint64_t __v = __arch_getq(c); __iormb(); __v; })
+#define writeq(v, c) \
+ ({ uint64_t __v = v; __iowmb(); __arch_putq(__v, c); __v; })
+#define writeq32(v, c) \
+ ({ uint32_t __v = v; __iowmb(); __arch_putq32(__v, c); __v; })
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+#define iowrite32(_v, _p) writeq32(_v, _p)
+#define __iomem
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+/*GPP is supposed to use MC commands with low priority*/
+#define CMD_PRI_LOW 0 /*!< Low Priority command indication */
+
+struct mc_command;
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* __linux_driver__ */
+
+#endif /* _FSL_MC_SYS_H */
diff --git a/drivers/bus/fslmc/mc/mc_sys.c b/drivers/bus/fslmc/mc/mc_sys.c
new file mode 100644
index 0000000..4573165
--- /dev/null
+++ b/drivers/bus/fslmc/mc/mc_sys.c
@@ -0,0 +1,114 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+
+#include <rte_spinlock.h>
+
+/** User space framework uses MC Portal in shared mode. Following change
+ * introduces lock in MC FLIB
+ */
+
+/**
+ * A static spinlock initializer.
+ */
+static rte_spinlock_t mc_portal_lock = RTE_SPINLOCK_INITIALIZER;
+
+static int mc_status_to_error(enum mc_cmd_status status)
+{
+ switch (status) {
+ case MC_CMD_STATUS_OK:
+ return 0;
+ case MC_CMD_STATUS_AUTH_ERR:
+ return -EACCES; /* Token error */
+ case MC_CMD_STATUS_NO_PRIVILEGE:
+ return -EPERM; /* Permission denied */
+ case MC_CMD_STATUS_DMA_ERR:
+ return -EIO; /* Input/Output error */
+ case MC_CMD_STATUS_CONFIG_ERR:
+ return -EINVAL; /* Device not configured */
+ case MC_CMD_STATUS_TIMEOUT:
+ return -ETIMEDOUT; /* Operation timed out */
+ case MC_CMD_STATUS_NO_RESOURCE:
+ return -ENAVAIL; /* Resource temporarily unavailable */
+ case MC_CMD_STATUS_NO_MEMORY:
+ return -ENOMEM; /* Cannot allocate memory */
+ case MC_CMD_STATUS_BUSY:
+ return -EBUSY; /* Device busy */
+ case MC_CMD_STATUS_UNSUPPORTED_OP:
+ return -ENOTSUP; /* Operation not supported by device */
+ case MC_CMD_STATUS_INVALID_STATE:
+ return -ENODEV; /* Invalid device state */
+ default:
+ break;
+ }
+
+ /* Not expected to reach here */
+ return -EINVAL;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+ enum mc_cmd_status status;
+
+ if (!mc_io || !mc_io->regs)
+ return -EACCES;
+
+ /* --- Call lock function here in case portal is shared --- */
+ rte_spinlock_lock(&mc_portal_lock);
+
+ mc_write_command(mc_io->regs, cmd);
+
+ /* Spin until status changes */
+ do {
+ status = MC_CMD_HDR_READ_STATUS(ioread64(mc_io->regs));
+
+ /* --- Call wait function here to prevent blocking ---
+ * Change the loop condition accordingly to exit on timeout.
+ */
+ } while (status == MC_CMD_STATUS_READY);
+
+ /* Read the response back into the command buffer */
+ mc_read_response(mc_io->regs, cmd);
+
+ /* --- Call unlock function here in case portal is shared --- */
+ rte_spinlock_unlock(&mc_portal_lock);
+
+ return mc_status_to_error(status);
+}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 05/33] bus/fslmc: add mc dpni object support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (3 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 04/33] bus/fslmc: introduce mc object functions Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 06/33] bus/fslmc: add mc dpio " Hemant Agrawal
` (30 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
This patch add support for dpni object support in MC
driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpni.c | 739 ++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpkg.h | 184 ++++
drivers/bus/fslmc/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 334 ++++++++
drivers/bus/fslmc/mc/fsl_net.h | 487 +++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 22 +
7 files changed, 2984 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 1058f0f..15ab89a 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -49,6 +49,7 @@ EXPORT_MAP := rte_bus_fslmc_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/dpni.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpni.c b/drivers/bus/fslmc/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpkg.h b/drivers/bus/fslmc/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni.h b/drivers/bus/fslmc/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni_cmd.h b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_net.h b/drivers/bus/fslmc/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4d525ba..d49dda8 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,5 +1,27 @@
DPDK_17.02 {
global:
+ dpni_close;
+ dpni_disable;
+ dpni_enable;
+ dpni_get_attributes;
+ dpni_get_link_state;
+ dpni_get_primary_mac_addr;
+ dpni_get_qdid;
+ dpni_get_queue;
+ dpni_get_statistics;
+ dpni_open;
+ dpni_prepare_key_cfg;
+ dpni_reset;
+ dpni_reset_statistics;
+ dpni_set_buffer_layout;
+ dpni_set_errors_behavior;
+ dpni_set_max_frame_length;
+ dpni_set_offload;
+ dpni_set_pools;
+ dpni_set_queue;
+ dpni_set_rx_tc_dist;
+ dpni_set_tx_confirmation_mode;
+ dpni_set_unicast_promisc;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 06/33] bus/fslmc: add mc dpio object support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (4 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 05/33] bus/fslmc: add mc dpni object support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 07/33] bus/fslmc: add mc dpbp " Hemant Agrawal
` (29 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
This patch adds the DPIO object support in MC driver.
DPIO - Data Path Input Output represent the processing
context to access the QBMAN HW for packet I/O.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpio.c | 279 +++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 8 +
5 files changed, 691 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 15ab89a..53ab17b 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpio.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpio.c b/drivers/bus/fslmc/mc/dpio.c
new file mode 100644
index 0000000..7f7359d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpio.c
@@ -0,0 +1,279 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpio.h>
+#include <fsl_dpio_cmd.h>
+
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPIO_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
+ cmd_flags,
+ token);
+ DPIO_CMD_SET_STASHING_DEST(cmd, sdest);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_STASHING_DEST,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_STASHING_DEST(cmd, *sdest);
+
+ return 0;
+}
+
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPIO_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpio.h b/drivers/bus/fslmc/mc/fsl_dpio.h
new file mode 100644
index 0000000..6d86f07
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio.h
@@ -0,0 +1,282 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPIO_H
+#define __FSL_DPIO_H
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and any MC portals
+ * assigned to the parent container; this token must be used in
+ * all subsequent commands for this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token);
+
+/**
+ * dpio_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * struct dpio_cfg - Structure representing DPIO configuration
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_cfg {
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_create() - Create the DPIO object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPIO object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpio_destroy() - Destroy the DPIO object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_is_enabled() - Check if the DPIO is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_set_stashing_destination() - Set the stashing destination.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest);
+
+/**
+ * dpio_get_stashing_destination() - Get the stashing destination..
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: Returns the stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ * @qbman_version: QBMAN version
+ */
+struct dpio_attr {
+ int id;
+ uint64_t qbman_portal_ce_offset;
+ uint64_t qbman_portal_ci_offset;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+ uint32_t qbman_version;
+ uint32_t clk;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+/**
+ * dpio_get_api_version() - Get Data Path I/O API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path i/o API
+ * @minor_ver: Minor version of data path i/o API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPIO_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpio_cmd.h b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
new file mode 100644
index 0000000..c4b613e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
@@ -0,0 +1,121 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPIO_CMD_H
+#define _FSL_DPIO_CMD_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 4
+#define DPIO_VER_MINOR 2
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPIO_CMDID_OPEN ((0x803 << 4) | (0x1))
+#define DPIO_CMDID_CREATE ((0x903 << 4) | (0x1))
+#define DPIO_CMDID_DESTROY ((0x983 << 4) | (0x1))
+#define DPIO_CMDID_GET_API_VERSION ((0xa03 << 4) | (0x1))
+
+#define DPIO_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPIO_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPIO_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPIO_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPIO_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPIO_CMDID_SET_STASHING_DEST ((0x120 << 4) | (0x1))
+#define DPIO_CMDID_GET_STASHING_DEST ((0x121 << 4) | (0x1))
+#define DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL ((0x122 << 4) | (0x1))
+#define DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL ((0x123 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 2, enum dpio_channel_mode, \
+ cfg->channel_mode);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->num_priorities);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
+ MC_RSP_OP(cmd, 3, 0, 32, uint32_t, attr->qbman_version);\
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, attr->clk);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_SET_STASHING_DEST(cmd, sdest) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_STASHING_DEST(cmd, sdest) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, channel_index) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, channel_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index d49dda8..daf6b8f 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,5 +1,13 @@
DPDK_17.02 {
global:
+
+ dpio_close;
+ dpio_disable;
+ dpio_enable;
+ dpio_get_attributes;
+ dpio_open;
+ dpio_reset;
+ dpio_set_stashing_destination;
dpni_close;
dpni_disable;
dpni_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 07/33] bus/fslmc: add mc dpbp object support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (5 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 06/33] bus/fslmc: add mc dpio " Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 08/33] bus/fslmc: add mc dpseci " Hemant Agrawal
` (28 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Alex Marginean, Hemant Agrawal
DPBP object represent a hw based buffer pool instance
in the DPAA2 hardware.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpbp.c | 237 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 ++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 5 +
5 files changed, 553 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 53ab17b..628e517 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpbp.c b/drivers/bus/fslmc/mc/dpbp.c
new file mode 100644
index 0000000..0d93e0c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpbp.c
@@ -0,0 +1,237 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpbp.h>
+#include <fsl_dpbp_cmd.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ (void)(cfg); /* unused */
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPBP_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp.h b/drivers/bus/fslmc/mc/fsl_dpbp.h
new file mode 100644
index 0000000..65262bd
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp.h
@@ -0,0 +1,227 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpbp_id: DPBP unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpbp_create function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_cfg - Structure representing DPBP configuration
+ * @options: place holder
+ */
+struct dpbp_cfg {
+ uint32_t options;
+};
+
+/**
+ * dpbp_create() - Create the DPBP object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPBP object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpbp_destroy() - Destroy the DPBP object and release all its resources.
+ * @dprc_token: Parent container token; '0' for default container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_is_enabled() - Check if the DPBP is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ uint16_t bpid;
+};
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/**
+ * dpbp_get_api_version() - Get buffer pool API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path buffer pool API
+ * @minor_ver: Minor version of data path buffer pool API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPBP_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
new file mode 100644
index 0000000..a6bfabe
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
@@ -0,0 +1,83 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPBP_CMD_H
+#define _FSL_DPBP_CMD_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 3
+#define DPBP_VER_MINOR 2
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPBP_CMDID_OPEN ((0x804 << 4) | (0x1))
+#define DPBP_CMDID_CREATE ((0x904 << 4) | (0x1))
+#define DPBP_CMDID_DESTROY ((0x984 << 4) | (0x1))
+#define DPBP_CMDID_GET_API_VERSION ((0xa04 << 4) | (0x1))
+
+#define DPBP_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPBP_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPBP_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPBP_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPBP_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPBP_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index daf6b8f..5167262 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,11 @@
DPDK_17.02 {
global:
+ dpbp_disable;
+ dpbp_enable;
+ dpbp_get_attributes;
+ dpbp_open;
+ dpbp_reset;
dpio_close;
dpio_disable;
dpio_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 08/33] bus/fslmc: add mc dpseci object support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (6 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 07/33] bus/fslmc: add mc dpbp " Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 09/33] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
` (27 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Cristian Sovaiala, Hemant Agrawal
dpseci represent a instance of SEC HW in DPAA2.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpseci.c | 534 ++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 668 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 255 +++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 10 +
5 files changed, 1468 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 628e517..4a118a3 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpseci.c \
mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpseci.c b/drivers/bus/fslmc/mc/dpseci.c
new file mode 100644
index 0000000..bc8c9c5
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpseci.c
@@ -0,0 +1,534 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpseci.h>
+#include <fsl_dpseci_cmd.h>
+
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPSECI_CMD_OPEN(cmd, dpseci_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPSECI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_IS_ENABLED,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ(cmd, *type, irq_cfg);
+
+ return 0;
+}
+
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_ENABLE(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_MASK(cmd, *mask);
+
+ return 0;
+}
+
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_STATUS(cmd, *status);
+
+ return 0;
+}
+
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLEAR_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_RX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_RX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_TX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_TX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_TX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_COUNTERS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters);
+
+ return 0;
+}
+
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPSECI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci.h b/drivers/bus/fslmc/mc/fsl_dpseci.h
new file mode 100644
index 0000000..b8c6dcc
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci.h
@@ -0,0 +1,668 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPSECI_H
+#define __FSL_DPSECI_H
+
+/* Data Path SEC Interface API
+ * Contains initialization APIs and runtime control APIs for DPSECI
+ */
+
+struct fsl_mc_io;
+
+/**
+ * General DPSECI macros
+ */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPSECI object
+ */
+#define DPSECI_PRIO_NUM 8
+
+/**
+ * All queues considered; see dpseci_set_rx_queue()
+ */
+#define DPSECI_ALL_QUEUES (uint8_t)(-1)
+
+/**
+ * dpseci_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpseci_id: DPSECI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpseci_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token);
+
+/**
+ * dpseci_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_cfg - Structure representing DPSECI configuration
+ * @num_tx_queues: num of queues towards the SEC
+ * @num_rx_queues: num of queues back from the SEC
+ * @priorities: Priorities for the SEC hardware processing;
+ * each place in the array is the priority of the tx queue
+ * towards the SEC,
+ * valid priorities are configured with values 1-8;
+ */
+struct dpseci_cfg {
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+ uint8_t priorities[DPSECI_PRIO_NUM];
+};
+
+/**
+ * dpseci_create() - Create the DPSECI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPSECI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpseci_destroy() - Destroy the DPSECI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpseci_enable() - Enable the DPSECI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_disable() - Disable the DPSECI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_is_enabled() - Check if the DPSECI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpseci_reset() - Reset the DPSECI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_irq_cfg - IRQ configuration
+ * @addr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+ * @irq_num: A user defined number associated with this IRQ
+ */
+struct dpseci_irq_cfg {
+ uint64_t addr;
+ uint32_t val;
+ int irq_num;
+};
+
+/**
+ * dpseci_set_irq() - Set IRQ information for the DPSECI to trigger an interrupt
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: Identifies the interrupt index to configure
+ * @irq_cfg: IRQ configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_get_irq() - Get IRQ information from the DPSECI
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @type: Interrupt type: 0 represents message interrupt
+ * type (both irq_addr and irq_val are valid)
+ * @irq_cfg: IRQ attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_set_irq_enable() - Set overall interrupt state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Interrupt state - enable = 1, disable = 0
+ *
+ * Allows GPP software to control when interrupts are generated.
+ * Each interrupt can have up to 32 causes. The enable/disable control's the
+ * overall interrupt state. if the interrupt is disabled no causes will cause
+ * an interrupt
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en);
+
+/**
+ * dpseci_get_irq_enable() - Get overall interrupt state
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Returned Interrupt state - enable = 1, disable = 0
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en);
+
+/**
+ * dpseci_set_irq_mask() - Set interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: event mask to trigger interrupt;
+ * each bit:
+ * 0 = ignore event
+ * 1 = consider event for asserting IRQ
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask);
+
+/**
+ * dpseci_get_irq_mask() - Get interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: Returned event mask to trigger interrupt
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask);
+
+/**
+ * dpseci_get_irq_status() - Get the current status of any pending interrupts
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: Returned interrupts status - one bit per cause:
+ * 0 = no interrupt pending
+ * 1 = interrupt pending
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status);
+
+/**
+ * dpseci_clear_irq_status() - Clear a pending interrupt's status
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: bits to clear (W1C) - one bit per cause:
+ * 0 = don't change
+ * 1 = clear status bit
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status);
+
+/**
+ * struct dpseci_attr - Structure representing DPSECI attributes
+ * @id: DPSECI object ID
+ * @num_tx_queues: number of queues towards the SEC
+ * @num_rx_queues: number of queues back from the SEC
+ */
+struct dpseci_attr {
+ int id;
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+};
+
+/**
+ * dpseci_get_attributes() - Retrieve DPSECI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr);
+
+/**
+ * enum dpseci_dest - DPSECI destination types
+ * @DPSECI_DEST_NONE: Unassigned destination; The queue is set in parked mode
+ * and does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPSECI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPSECI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpseci_dest {
+ DPSECI_DEST_NONE = 0,
+ DPSECI_DEST_DPIO = 1,
+ DPSECI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpseci_dest_cfg - Structure representing DPSECI destination parameters
+ * @dest_type: Destination type
+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
+ * are 0-1 or 0-7, depending on the number of priorities in that
+ * channel; not relevant for 'DPSECI_DEST_NONE' option
+ */
+struct dpseci_dest_cfg {
+ enum dpseci_dest dest_type;
+ int dest_id;
+ uint8_t priority;
+};
+
+/**
+ * DPSECI queue modification options
+ */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPSECI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPSECI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Select to modify the queue's order preservation
+ */
+#define DPSECI_QUEUE_OPT_ORDER_PRESERVATION 0x00000004
+
+/**
+ * struct dpseci_rx_queue_cfg - DPSECI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ * Use any combination of 'DPSECI_QUEUE_OPT_<X>' flags
+ * @order_preservation_en: order preservation configuration for the rx queue
+ * valid only if 'DPSECI_QUEUE_OPT_ORDER_PRESERVATION' is contained in 'options'
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame;
+ * valid only if 'DPSECI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ * valid only if 'DPSECI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpseci_rx_queue_cfg {
+ uint32_t options;
+ int order_preservation_en;
+ uint64_t user_ctx;
+ struct dpseci_dest_cfg dest_cfg;
+};
+
+/**
+ * dpseci_set_rx_queue() - Set Rx queue configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation; use
+ * DPSECI_ALL_QUEUES to configure all Rx queues identically.
+ * @cfg: Rx queue configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg);
+
+/**
+ * struct dpseci_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame
+ * @order_preservation_en: Status of the order preservation configuration
+ * on the queue
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpseci_rx_queue_attr {
+ uint64_t user_ctx;
+ int order_preservation_en;
+ struct dpseci_dest_cfg dest_cfg;
+ uint32_t fqid;
+};
+
+/**
+ * dpseci_get_rx_queue() - Retrieve Rx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Rx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr);
+
+/**
+ * struct dpseci_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to SEC hardware
+ * @priority: SEC hardware processing priority for the queue
+ */
+struct dpseci_tx_queue_attr {
+ uint32_t fqid;
+ uint8_t priority;
+};
+
+/**
+ * dpseci_get_tx_queue() - Retrieve Tx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Tx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr);
+
+/**
+ * struct dpseci_sec_attr - Structure representing attributes of the SEC
+ * hardware accelerator
+ * @ip_id: ID for SEC.
+ * @major_rev: Major revision number for SEC.
+ * @minor_rev: Minor revision number for SEC.
+ * @era: SEC Era.
+ * @deco_num: The number of copies of the DECO that are implemented in
+ * this version of SEC.
+ * @zuc_auth_acc_num: The number of copies of ZUCA that are implemented
+ * in this version of SEC.
+ * @zuc_enc_acc_num: The number of copies of ZUCE that are implemented
+ * in this version of SEC.
+ * @snow_f8_acc_num: The number of copies of the SNOW-f8 module that are
+ * implemented in this version of SEC.
+ * @snow_f9_acc_num: The number of copies of the SNOW-f9 module that are
+ * implemented in this version of SEC.
+ * @crc_acc_num: The number of copies of the CRC module that are implemented
+ * in this version of SEC.
+ * @pk_acc_num: The number of copies of the Public Key module that are
+ * implemented in this version of SEC.
+ * @kasumi_acc_num: The number of copies of the Kasumi module that are
+ * implemented in this version of SEC.
+ * @rng_acc_num: The number of copies of the Random Number Generator that are
+ * implemented in this version of SEC.
+ * @md_acc_num: The number of copies of the MDHA (Hashing module) that are
+ * implemented in this version of SEC.
+ * @arc4_acc_num: The number of copies of the ARC4 module that are implemented
+ * in this version of SEC.
+ * @des_acc_num: The number of copies of the DES module that are implemented
+ * in this version of SEC.
+ * @aes_acc_num: The number of copies of the AES module that are implemented
+ * in this version of SEC.
+ **/
+
+struct dpseci_sec_attr {
+ uint16_t ip_id;
+ uint8_t major_rev;
+ uint8_t minor_rev;
+ uint8_t era;
+ uint8_t deco_num;
+ uint8_t zuc_auth_acc_num;
+ uint8_t zuc_enc_acc_num;
+ uint8_t snow_f8_acc_num;
+ uint8_t snow_f9_acc_num;
+ uint8_t crc_acc_num;
+ uint8_t pk_acc_num;
+ uint8_t kasumi_acc_num;
+ uint8_t rng_acc_num;
+ uint8_t md_acc_num;
+ uint8_t arc4_acc_num;
+ uint8_t des_acc_num;
+ uint8_t aes_acc_num;
+};
+
+/**
+ * dpseci_get_sec_attr() - Retrieve SEC accelerator attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned SEC attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr);
+
+/**
+ * struct dpseci_sec_counters - Structure representing global SEC counters and
+ * not per dpseci counters
+ * @dequeued_requests: Number of Requests Dequeued
+ * @ob_enc_requests: Number of Outbound Encrypt Requests
+ * @ib_dec_requests: Number of Inbound Decrypt Requests
+ * @ob_enc_bytes: Number of Outbound Bytes Encrypted
+ * @ob_prot_bytes: Number of Outbound Bytes Protected
+ * @ib_dec_bytes: Number of Inbound Bytes Decrypted
+ * @ib_valid_bytes: Number of Inbound Bytes Validated
+ */
+struct dpseci_sec_counters {
+ uint64_t dequeued_requests;
+ uint64_t ob_enc_requests;
+ uint64_t ib_dec_requests;
+ uint64_t ob_enc_bytes;
+ uint64_t ob_prot_bytes;
+ uint64_t ib_dec_bytes;
+ uint64_t ib_valid_bytes;
+};
+
+/**
+ * dpseci_get_sec_counters() - Retrieve SEC accelerator counters.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @counters: Returned SEC counters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters);
+
+/**
+ * dpseci_get_api_version() - Get Data Path SEC Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path sec API
+ * @minor_ver: Minor version of data path sec API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPSECI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
new file mode 100644
index 0000000..97494f4
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
@@ -0,0 +1,255 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPSECI_CMD_H
+#define _FSL_DPSECI_CMD_H
+
+/* DPSECI Version */
+#define DPSECI_VER_MAJOR 5
+#define DPSECI_VER_MINOR 0
+
+/* Command IDs */
+#define DPSECI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPSECI_CMDID_OPEN ((0x809 << 4) | (0x1))
+#define DPSECI_CMDID_CREATE ((0x909 << 4) | (0x1))
+#define DPSECI_CMDID_DESTROY ((0x989 << 4) | (0x1))
+#define DPSECI_CMDID_GET_API_VERSION ((0xa09 << 4) | (0x1))
+
+#define DPSECI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPSECI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPSECI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPSECI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPSECI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_IRQ ((0x010 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ ((0x011 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_ENABLE ((0x012 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_ENABLE ((0x013 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_MASK ((0x014 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_MASK ((0x015 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_STATUS ((0x016 << 4) | (0x1))
+#define DPSECI_CMDID_CLEAR_IRQ_STATUS ((0x017 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_RX_QUEUE ((0x194 << 4) | (0x1))
+#define DPSECI_CMDID_GET_RX_QUEUE ((0x196 << 4) | (0x1))
+#define DPSECI_CMDID_GET_TX_QUEUE ((0x197 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_ATTR ((0x198 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_COUNTERS ((0x199 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_OPEN(cmd, dpseci_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpseci_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->priorities[0]);\
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, cfg->priorities[1]);\
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->priorities[2]);\
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->priorities[3]);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->priorities[4]);\
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->priorities[5]);\
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->priorities[6]);\
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->priorities[7]);\
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->num_tx_queues);\
+ MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->num_rx_queues);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ(cmd, type, irq_cfg) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+ MC_RSP_OP(cmd, 2, 32, 32, int, type); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, enable_state) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, enable_state); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, enable_state)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_MASK(cmd, mask) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_STATUS(cmd, status) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->num_tx_queues); \
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->num_rx_queues); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue); \
+ MC_CMD_OP(cmd, 0, 48, 4, enum dpseci_dest, cfg->dest_cfg.dest_type); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
+ MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\
+ MC_CMD_OP(cmd, 2, 32, 1, int, cfg->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_RX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_RX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 48, 4, enum dpseci_dest, attr->dest_cfg.dest_type);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint64_t, attr->user_ctx);\
+ MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 2, 32, 1, int, attr->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_TX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_TX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->priority);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, attr->ip_id);\
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->major_rev);\
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, attr->minor_rev);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->era);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->deco_num);\
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->zuc_auth_acc_num);\
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, attr->zuc_enc_acc_num);\
+ MC_RSP_OP(cmd, 1, 32, 8, uint8_t, attr->snow_f8_acc_num);\
+ MC_RSP_OP(cmd, 1, 40, 8, uint8_t, attr->snow_f9_acc_num);\
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, attr->crc_acc_num);\
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->pk_acc_num);\
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->kasumi_acc_num);\
+ MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->rng_acc_num);\
+ MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->md_acc_num);\
+ MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->arc4_acc_num);\
+ MC_RSP_OP(cmd, 2, 48, 8, uint8_t, attr->des_acc_num);\
+ MC_RSP_OP(cmd, 2, 56, 8, uint8_t, attr->aes_acc_num);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, counters->dequeued_requests);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counters->ob_enc_requests);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, counters->ib_dec_requests);\
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, counters->ob_enc_bytes);\
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, counters->ob_prot_bytes);\
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, counters->ib_dec_bytes);\
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, counters->ib_valid_bytes);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPSECI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 5167262..c4b3408 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -35,6 +35,16 @@ DPDK_17.02 {
dpni_set_rx_tc_dist;
dpni_set_tx_confirmation_mode;
dpni_set_unicast_promisc;
+ dpseci_close;
+ dpseci_disable;
+ dpseci_enable;
+ dpseci_get_attributes;
+ dpseci_get_rx_queue;
+ dpseci_get_sec_counters;
+ dpseci_get_tx_queue;
+ dpseci_open;
+ dpseci_reset;
+ dpseci_set_rx_queue;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 09/33] eal/vfio: adding vfio utility functions in map file
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (7 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 08/33] bus/fslmc: add mc dpseci " Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 10/33] bus/fslmc: add vfio support Hemant Agrawal
` (26 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
adding extra vfio utility functions to map file.
They will be used by other vfio supported buses like fslmc bus
for NXP DPAA2 devices
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +++
2 files changed, 6 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2cf1ac8..a74625a 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -183,5 +183,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 3c68ff5..99d4446 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -187,5 +187,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 10/33] bus/fslmc: add vfio support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (8 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 09/33] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 11/33] bus/fslmc: scan for net and sec devices Hemant Agrawal
` (25 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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>
---
drivers/bus/fslmc/Makefile | 2 +
drivers/bus/fslmc/fslmc_bus.c | 10 +
drivers/bus/fslmc/fslmc_vfio.c | 450 ++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 74 +++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
5 files changed, 537 insertions(+)
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 4a118a3..7cccc0e 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_bus_fslmc_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 8a4f519..ee794e7 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -42,6 +42,7 @@
#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)
@@ -51,6 +52,15 @@
static int
rte_fslmc_scan(void)
{
+ if (fslmc_vfio_setup_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup VFIO");
+ return -1;
+ }
+ if (fslmc_vfio_process_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
+ return -1;
+ }
+ 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
new file mode 100644
index 0000000..73db595
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -0,0 +1,450 @@
+/*-
+ * 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_FSL_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 *(*rte_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, ®_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(void)
+{
+ 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 */
+ rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
+ if (!rte_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);
+
+ rte_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)
+{
+ struct fslmc_vfio_group *group = NULL;
+ int groupid;
+ int ret, 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;
+ }
+ /* get group number */
+ ret = vfio_get_group_no(SYSFS_FSL_MC_DEVICES, container, &groupid);
+ if (ret == 0) {
+ RTE_LOG(WARNING, EAL, "%s not managed by VFIO, skipping\n",
+ container);
+ return 1;
+ }
+
+ /* if negative, something failed */
+ if (ret < 0)
+ return -1;
+
+ 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;
+ }
+ }
+
+ /* get the actual group fd */
+ group->fd = vfio_get_group_fd(groupid);
+ if (group->fd < 0)
+ return -1;
+
+ /*
+ * at this point, we know that this group is viable (meaning,
+ * all devices are either bound to VFIO or not bound to anything)
+ */
+
+ 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..5e58211
--- /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(void);
+
+#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index c4b3408..23aff2e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -47,6 +47,7 @@ DPDK_17.02 {
dpseci_set_rx_queue;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_mcp_ptr_list;
local: *;
};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 11/33] bus/fslmc: scan for net and sec devices
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (9 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 10/33] bus/fslmc: add vfio support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
` (24 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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_vfio.c | 63 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 73db595..0d4c0a2 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -210,6 +210,48 @@ 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 != DPAA2_MC_DPNI_DEVID ||
+ dev->dev_type != DPAA2_MC_DPSECI_DEVID)
+ return -1;
+
+ if (dev->object_id == dev2->object_id)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+fslmc_bus_add_device(struct rte_dpaa2_device *dev)
+{
+ struct rte_fslmc_device_list *dev_l;
+
+ dev_l = &rte_fslmc_bus.device_list;
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(dev_l)) {
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ } else {
+ struct rte_dpaa2_device *dev2;
+ int ret;
+
+ TAILQ_FOREACH(dev2, dev_l, next) {
+ ret = dpaa2_compare_dpaa2_dev(dev, dev2);
+ if (ret <= 0)
+ continue;
+
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ return;
+ }
+
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ }
+}
+
/* Following function shall fetch total available list of MC devices
* from VFIO container & populate private list of devices and other
* data structures
@@ -218,7 +260,7 @@ int fslmc_vfio_process_group(void)
{
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;
@@ -348,6 +390,25 @@ int fslmc_vfio_process_group(void)
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);
+
+ fslmc_bus_add_device(dev);
+ }
}
closedir(d);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (10 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 11/33] bus/fslmc: scan for net and sec devices Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 17:32 ` Ferruh Yigit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 13/33] doc: add dpaa2 nic details Hemant Agrawal
` (23 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 1 +
config/common_base | 4 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/bus/Makefile | 2 +
drivers/bus/fslmc/Makefile | 4 +
drivers/common/Makefile | 4 +
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 59 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 142 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 3 +
14 files changed, 281 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/MAINTAINERS b/MAINTAINERS
index 4a13140..7e274e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -358,6 +358,7 @@ NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index bf1de8f..7054999 100644
--- a/config/common_base
+++ b/config/common_base
@@ -292,6 +292,10 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=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 365ae5a..e63ff56 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -46,3 +46,8 @@ CONFIG_RTE_MAX_NUMA_NODES=1
# 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/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 7cccc0e..ce799da 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -35,6 +35,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_bus_fslmc.a
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
CFLAGS += "-Wno-strict-aliasing"
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index cba1134..b52931c 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
index 9681729..87f08bb 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 7ac1ba7..18bca6b 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -36,6 +36,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_common_dpaa2_qbman.a
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 40fc333..c2f64ce 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
DIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
@@ -57,7 +58,6 @@ 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
-
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..f85aa9f
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,59 @@
+# BSD LICENSE
+#
+# Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# Copyright (c) 2016 NXP. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Freescale Semiconductor, Inc nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
+
+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..bdef362
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,142 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = (struct eth_driver *)dpaa2_drv;
+
+ sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ sizeof(struct dpaa2_dev_priv),
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL) {
+ RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
+ " private port data\n");
+ rte_eth_dev_release_port(eth_dev);
+ 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;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .probe = rte_dpaa2_probe,
+ .remove = rte_dpaa2_remove,
+};
+
+
+RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd);
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
new file mode 100644
index 0000000..5778780
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -0,0 +1,44 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (c) 2016 NXP. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DPAA2_ETHDEV_H
+#define _DPAA2_ETHDEV_H
+
+struct dpaa2_dev_priv {
+ void *hw;
+ int32_t hw_id;
+ uint16_t token;
+
+ uint8_t flags; /*dpaa2 config flags */
+};
+#endif /* _DPAA2_ETHDEV_H */
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
new file mode 100644
index 0000000..31eca32
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.02 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a5daa84..c8a6c11 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -110,6 +110,9 @@ _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
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_common_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
@ 2017-01-23 17:32 ` Ferruh Yigit
2017-01-24 8:38 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:32 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> add support for fsl-mc bus based dpaa2 pmd driver.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> new file mode 100644
> index 0000000..f85aa9f
> --- /dev/null
> +++ b/drivers/net/dpaa2/Makefile
<...>
> +
> +# library dependencies
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
Is this dependency correct?
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver
2017-01-23 17:32 ` Ferruh Yigit
@ 2017-01-24 8:38 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-24 8:38 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Hemant Agrawal, dev, thomas.monjalon, bruce.richardson,
john.mcnamara, jerin.jacob
On Monday 23 January 2017 11:02 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> add support for fsl-mc bus based dpaa2 pmd driver.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
> <...>
>
>> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
>> new file mode 100644
>> index 0000000..f85aa9f
>> --- /dev/null
>> +++ b/drivers/net/dpaa2/Makefile
> <...>
>> +
>> +# library dependencies
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
>
> Is this dependency correct?
I think yes.
- Without Bus, dpaa2 PMD wouldn't work and being a configurable option,
user can set CONFIG_RTE_LIBRTE_DPAA2_PMD=n and
CONFIG_RTE_LIBRTE_DPAA2_PMD=y.
- If you referring to whether lib/librte_bus_fslmc is correct or not, I
have replied to your response on 16/33 patch. In short, I think this
is correct assuming that librte_bus_fslmc is valid LIB name and not
expected to be a folder in lib/
>
>> +
>> +include $(RTE_SDK)/mk/rte.lib.mk
>
> <...>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 13/33] doc: add dpaa2 nic details
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (11 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 12/33] net/dpaa2: introducing NXP dpaa2 pmd driver Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 14/33] bus/fslmc: add debug log message support Hemant Agrawal
` (22 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 593 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
5 files changed, 615 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e274e0..fb85351 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -359,6 +359,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..f0d7a26
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,593 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+This driver relies on external libraries and kernel drivers for resources
+allocations and initialization. The following dependencies are not part of
+DPDK and must be installed separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 87f9334..be21e8a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 0ecd720..d755a4d 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -15,7 +15,6 @@ DPDK Release 17.02
firefox build/doc/html/guides/rel_notes/release_17_02.html
-
New Features
------------
@@ -193,6 +192,17 @@ New Features
See the :ref:`Elastic Flow Distributor Library <Efd_Library>` documentation in
the Programmers Guide document, for more information.
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
Resolved Issues
---------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 14/33] bus/fslmc: add debug log message support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (12 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 13/33] doc: add dpaa2 nic details Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 15/33] drivers/common/dpaa2: dpio portal driver Hemant Agrawal
` (21 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 | 9 +++-
7 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
diff --git a/config/common_base b/config/common_base
index 7054999..d1bf7a0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -296,6 +296,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 e63ff56..eb12511 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -51,3 +51,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 ce799da..77e0a1b 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -39,8 +39,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+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 18bca6b..771bdc6 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -44,8 +44,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
+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 f85aa9f..6e0396a 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 bdef362..ead6a2c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -95,8 +100,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 15/33] drivers/common/dpaa2: dpio portal driver
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (13 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 14/33] bus/fslmc: add debug log message support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool Hemant Agrawal
` (20 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
The portal 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 | 3 +
drivers/bus/fslmc/fslmc_vfio.c | 17 +-
drivers/bus/fslmc/fslmc_vfio.h | 5 +
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 364 ++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 60 +++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 68 ++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
7 files changed, 518 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 77e0a1b..311e0e9 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ 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)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -65,10 +66,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpio.c \
mc/mc_sys.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_common_dpaa2_qbman
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 0d4c0a2..2d7bcd9 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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
#define VFIO_MAX_CONTAINERS 1
#define FSLMC_VFIO_LOG(level, fmt, args...) \
@@ -261,12 +264,13 @@ int fslmc_vfio_process_group(void)
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;
@@ -409,9 +413,20 @@ int fslmc_vfio_process_group(void)
fslmc_bus_add_device(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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5e58211..39994dd 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -71,4 +71,9 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(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_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
new file mode 100644
index 0000000..dd6de4c
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+
+ reg_info.index = 0;
+ if (ioctl(dpio_dev->vfio_fd, VFIO_DEVICE_GET_REGION_INFO, ®_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, ®_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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
new file mode 100644
index 0000000..682f3fa
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -0,0 +1,60 @@
+/*-
+ * 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_DPIO_H_
+#define _DPAA2_HW_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);
+
+
+#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
new file mode 100644
index 0000000..6b44314
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 *(*rte_mcp_ptr_list);
+#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 23aff2e..48d776e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,7 @@
DPDK_17.02 {
global:
+ dpaa2_affine_qbman_swp;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
@@ -45,6 +46,7 @@ DPDK_17.02 {
dpseci_open;
dpseci_reset;
dpseci_set_rx_queue;
+ per_lcore__dpaa2_io;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
rte_mcp_ptr_list;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (14 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 15/33] drivers/common/dpaa2: dpio portal driver Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 17:34 ` Ferruh Yigit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads Hemant Agrawal
` (19 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +
drivers/Makefile | 1 +
drivers/bus/fslmc/Makefile | 2 +
drivers/bus/fslmc/fslmc_vfio.c | 9 +-
drivers/bus/fslmc/fslmc_vfio.h | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 +++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
drivers/common/Makefile | 6 +-
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
drivers/pool/Makefile | 40 +++
drivers/pool/dpaa2/Makefile | 71 ++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339 ++++++++++++++++++++++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
mk/rte.app.mk | 1 +
19 files changed, 753 insertions(+), 2 deletions(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
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_pool_dpaa2_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index fb85351..a3ebcd5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -359,6 +359,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
F: drivers/net/dpaa2/
+F: drivers/pool/dpaa2/
F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
diff --git a/config/common_base b/config/common_base
index d1bf7a0..dd3de11 100644
--- a/config/common_base
+++ b/config/common_base
@@ -288,6 +288,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile Support Libraries for NXP DPAA2
+#
+CONFIG_RTE_LIBRTE_DPAA2_POOL=n
+
+#
# Compile NXP DPAA2 FSL-MC Bus
#
CONFIG_RTE_LIBRTE_FSLMC_BUS=n
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index eb12511..3cdb31b 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -42,6 +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_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..9fd268e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
DIRS-y += bus
+DIRS-y += pool
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 311e0e9..263c4fd 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -51,6 +51,7 @@ 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/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -67,6 +68,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 2d7bcd9..fc017fc 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -270,7 +270,7 @@ int fslmc_vfio_process_group(void)
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 +420,11 @@ int fslmc_vfio_process_group(void)
if (!ret)
dpio_count++;
}
+ if (!strcmp(object_type, "dpbp")) {
+ ret = dpaa2_create_dpbp_device(object_id);
+ if (!ret)
+ dpbp_count++;
+ }
}
closedir(d);
@@ -427,6 +432,8 @@ int fslmc_vfio_process_group(void)
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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 39994dd..80c6869 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -76,4 +76,6 @@ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
struct vfio_device_info *obj_info,
int object_id);
+int dpaa2_create_dpbp_device(int dpbp_id);
+
#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
new file mode 100644
index 0000000..894f632
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
@@ -0,0 +1,137 @@
+/*-
+ * 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_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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
+TAILQ_HEAD(dpbp_device_list, dpaa2_dpbp_dev);
+static struct dpbp_device_list *dpbp_dev_list; /*!< DPBP device list */
+
+int
+dpaa2_create_dpbp_device(
+ int dpbp_id)
+{
+ struct dpaa2_dpbp_dev *dpbp_node;
+ int ret;
+
+ if (!dpbp_dev_list) {
+ dpbp_dev_list = malloc(sizeof(struct dpbp_device_list));
+ if (!dpbp_dev_list) {
+ PMD_INIT_LOG(ERR, "Memory alloc failed in DPBP list\n");
+ return -1;
+ }
+ /* Initialize the DPBP List */
+ TAILQ_INIT(dpbp_dev_list);
+ }
+
+ /* Allocate DPAA2 dpbp handle */
+ dpbp_node = (struct dpaa2_dpbp_dev *)
+ malloc(sizeof(struct dpaa2_dpbp_dev));
+ if (!dpbp_node) {
+ PMD_INIT_LOG(ERR, "Memory allocation failed for DPBP Device");
+ return -1;
+ }
+
+ /* Open the dpbp object */
+ dpbp_node->dpbp.regs = rte_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;
+ rte_atomic16_init(&dpbp_node->in_use);
+
+ TAILQ_INSERT_HEAD(dpbp_dev_list, dpbp_node, next);
+
+ PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
+
+ return 0;
+}
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Get DPBP dev handle from list using index */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
+ break;
+ }
+
+ return dpbp_dev;
+}
+
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Match DPBP handle and mark it free */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev == dpbp) {
+ rte_atomic16_dec(&dpbp_dev->in_use);
+ return;
+ }
+ }
+}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 6b44314..ad2847f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -63,6 +70,19 @@ struct dpaa2_dpio_dev {
int32_t hw_id; /**< An unique ID of this DPIO device instance */
};
+struct dpaa2_dpbp_dev {
+ TAILQ_ENTRY(dpaa2_dpbp_dev) next;
+ /**< Pointer to Next device instance */
+ struct fsl_mc_io dpbp; /** handle to DPBP portal object */
+ uint16_t token;
+ rte_atomic16_t in_use;
+ uint32_t dpbp_id; /*HW ID for DPBP object */
+};
+
/*! Global MCP list */
extern void *(*rte_mcp_ptr_list);
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
+
#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 48d776e..028f55e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,8 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_alloc_dpbp_dev;
+ dpaa2_free_dpbp_dev;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index b52931c..0bb75b5 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
-ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
+ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
index 87f08bb..35e9405 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -35,6 +35,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 771bdc6..ee53ad7 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -40,6 +40,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/pool/Makefile b/drivers/pool/Makefile
new file mode 100644
index 0000000..3efc336
--- /dev/null
+++ b/drivers/pool/Makefile
@@ -0,0 +1,40 @@
+# 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
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += 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..69e1bb4
--- /dev/null
+++ b/drivers/pool/dpaa2/Makefile
@@ -0,0 +1,71 @@
+# 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_pool_dpaa2.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+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_pool_dpaa2_version.map
+
+# Lbrary version
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += dpaa2_hw_mempool.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
+
+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..0c8de51
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -0,0 +1,339 @@
+/*-
+ * 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 <mc/fsl_dpbp.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+#include "dpaa2_hw_mempool.h"
+
+struct dpaa2_bp_info rte_dpaa2_bpid_info[MAX_BPID];
+static struct dpaa2_bp_list *h_bp_list;
+
+static int
+hw_mbuf_create_pool(struct rte_mempool *mp)
+{
+ struct dpaa2_bp_list *bp_list;
+ struct dpaa2_dpbp_dev *avail_dpbp;
+ struct dpbp_attr dpbp_attr;
+ uint32_t bpid;
+ int ret;
+
+ avail_dpbp = dpaa2_alloc_dpbp_dev();
+
+ if (!avail_dpbp) {
+ PMD_DRV_LOG(ERR, "DPAA2 resources not available");
+ return -1;
+ }
+
+ if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+ ret = dpaa2_affine_qbman_swp();
+ if (ret) {
+ RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+ return 0;
+ }
+ }
+
+ 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;
+
+
+ rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
+ + rte_pktmbuf_priv_size(mp);
+ rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
+ rte_dpaa2_bpid_info[bpid].bpid = bpid;
+
+ mp->pool_data = (void *)&rte_dpaa2_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)
+{
+ struct dpaa2_bp_info *bpinfo;
+ struct dpaa2_bp_list *bp;
+ struct dpaa2_dpbp_dev *dpbp_node;
+
+ if (!mp->pool_data) {
+ PMD_DRV_LOG(ERR, "Not a valid dpaa22 pool");
+ return;
+ }
+
+ bpinfo = (struct dpaa2_bp_info *)mp->pool_data;
+ bp = bpinfo->bp_list;
+ dpbp_node = bp->buf_pool.dpbp_node;
+
+ dpbp_disable(&(dpbp_node->dpbp), CMD_PRI_LOW, dpbp_node->token);
+
+ if (h_bp_list == bp) {
+ h_bp_list = h_bp_list->next;
+ } else { /* if it is not the first node */
+ struct dpaa2_bp_list *prev = h_bp_list, *temp;
+ temp = h_bp_list->next;
+ while (temp) {
+ if (temp == bp) {
+ prev->next = temp->next;
+ free(bp);
+ break;
+ }
+ prev = temp;
+ temp = temp->next;
+ }
+ }
+
+ dpaa2_free_dpbp_dev(dpbp_node);
+}
+
+static
+void rte_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 rte_dpaa2_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 */
+ rte_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;
+ }
+ rte_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 = rte_dpaa2_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..c0e2411
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
@@ -0,0 +1,95 @@
+/*-
+ * 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 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 dpaa2_dpbp_dev *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 rte_dpaa2_bpid_info[MAX_BPID];
+
+int rte_dpaa2_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_pool_dpaa2_version.map b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
new file mode 100644
index 0000000..187f092
--- /dev/null
+++ b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
@@ -0,0 +1,8 @@
+DPDK_17.02 {
+ global:
+
+ rte_dpaa2_bpid_info;
+ rte_dpaa2_mbuf_alloc_bulk;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c8a6c11..ea6ac49 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -112,6 +112,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_common_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pool_dpaa2
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool Hemant Agrawal
@ 2017-01-23 17:34 ` Ferruh Yigit
2017-01-24 9:12 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:34 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> 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>
> ---
<...>
> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
> index b52931c..0bb75b5 100644
> --- a/drivers/common/Makefile
> +++ b/drivers/common/Makefile
> @@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
> endif
>
> -ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
> +endif
> +
> +ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
I guess this is a typo, but this prevents DPAA2_COMMON to be compiled !!
> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
> endif
>
<...>
> +# library dependencies
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
This dependeny doesn not looks correct, there is no folder like that.
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-23 17:34 ` Ferruh Yigit
@ 2017-01-24 9:12 ` Shreyansh Jain
2017-01-24 10:49 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-24 9:12 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Hemant Agrawal, dev, thomas.monjalon, bruce.richardson,
john.mcnamara, jerin.jacob
On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> 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>
>> ---
> <...>
>
>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>> index b52931c..0bb75b5 100644
>> --- a/drivers/common/Makefile
>> +++ b/drivers/common/Makefile
>> @@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>> endif
>>
>> -ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
>> +endif
>> +
>> +ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>
> I guess this is a typo, but this prevents DPAA2_COMMON to be compiled !!
It should be 'ifeq' rather than 'ifneq'. And it will prevent COMMON
compilation only if CONFIG_RTE_LIBRTE_FSLMC_BUS=n which is not the case
right now.
We will fix it.
>
>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
>> endif
>>
>
> <...>
>> +# library dependencies
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>
> This dependeny doesn not looks correct, there is no folder like that.
This is something even I need to understand. From the DEPDIRS what I
understood was that though it refers to a directory, it essentially
links libraries in build/lib/*.
Further, somehow the development is deploying drivers/bus,
drivers/common and drivers/pool in lib/* under the name specified as
LIB in Makefile. My understanding was that it is expected behavior and
not special because of drivers folder.
Thus, above line only links lib/librte_common_dpaa2_qbman generated by
drivers/common/dpaa2/qbman code.
In fact, I think, this might also one of the issues why a parallel
shared build fails for DPAA2 PMD (added in Cover letter).
The dependency graph cannot create a graph for drivers/common
as dependency for drivers/net or drivers/bus and hence parallel build
fails because of missing libraries which are being parallely compiled.
>
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
>> +
>> +include $(RTE_SDK)/mk/rte.lib.mk
>
> <...>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 9:12 ` Shreyansh Jain
@ 2017-01-24 10:49 ` Ferruh Yigit
2017-01-24 14:37 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-24 10:49 UTC (permalink / raw)
To: Shreyansh Jain
Cc: Hemant Agrawal, dev, thomas.monjalon, bruce.richardson,
john.mcnamara, jerin.jacob
On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>> 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>
>>> ---
>> <...>
>>
>>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>>> index b52931c..0bb75b5 100644
>>> --- a/drivers/common/Makefile
>>> +++ b/drivers/common/Makefile
>>> @@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>>> endif
>>>
>>> -ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
>>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
>>> +endif
>>> +
>>> +ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>
>> I guess this is a typo, but this prevents DPAA2_COMMON to be compiled !!
>
> It should be 'ifeq' rather than 'ifneq'.
> And it will prevent COMMON
> compilation only if CONFIG_RTE_LIBRTE_FSLMC_BUS=n which is not the case
> right now.
It was the case for me for x86 config, but you are right it is not the
default case for arm.
>
> We will fix it.
>
>>
>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
>>> endif
>>>
>>
>> <...>
>>> +# library dependencies
>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>>
>> This dependeny doesn not looks correct, there is no folder like that.
>
> This is something even I need to understand. From the DEPDIRS what I
> understood was that though it refers to a directory, it essentially
> links libraries in build/lib/*.
>
> Further, somehow the development is deploying drivers/bus,
> drivers/common and drivers/pool in lib/* under the name specified as
> LIB in Makefile. My understanding was that it is expected behavior and
> not special because of drivers folder.
>
> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> drivers/common/dpaa2/qbman code.
>
> In fact, I think, this might also one of the issues why a parallel
> shared build fails for DPAA2 PMD (added in Cover letter).
> The dependency graph cannot create a graph for drivers/common
> as dependency for drivers/net or drivers/bus and hence parallel build
> fails because of missing libraries which are being parallely compiled.
DEPDIRS-y is mainly to resolve dependencies for compilation order, and
should point to the folder,
Following line will cause "librte_eal" to be compiled before driver:
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
there is no folder like that.
Somewhere in the history, with following commit, DEPDIRS-y gained a side
effect, it has been used to set dynamic linking dependencies, to fix
underlinking issue:
bf5a46fa5972 ("mk: generate internal library dependencies")
I guess you are having that line to benefit from this side effect, but
this can be done with following more properly:
LDLIBS += lib/librte_common_dpaa2_qbman
To resolve the drivers/net to drivers/common dependency, following line
in this Makefile should work:
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
This adds following, which will cause "drivers/common" compiled before
any "drivers/net":
LOCAL_DEPDIRS-drivers/net += drivers/common
>
>>
>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
>>> +
>>> +include $(RTE_SDK)/mk/rte.lib.mk
>>
>> <...>
>>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 10:49 ` Ferruh Yigit
@ 2017-01-24 14:37 ` Hemant Agrawal
2017-01-24 16:35 ` Ferruh Yigit
2017-01-24 17:28 ` Thomas Monjalon
0 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-24 14:37 UTC (permalink / raw)
To: Ferruh Yigit, Shreyansh Jain
Cc: dev, thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob
On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
>> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
>>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>>> 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>
>>>> ---
>>> <...>
>>>
>>>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>>>> index b52931c..0bb75b5 100644
>>>> --- a/drivers/common/Makefile
>>>> +++ b/drivers/common/Makefile
>>>> @@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
>>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>>>> endif
>>>>
>>>> -ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
>>>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
>>>> +endif
>>>> +
>>>> +ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>>
>>> I guess this is a typo, but this prevents DPAA2_COMMON to be compiled !!
>>
>> It should be 'ifeq' rather than 'ifneq'.
>
>> And it will prevent COMMON
>> compilation only if CONFIG_RTE_LIBRTE_FSLMC_BUS=n which is not the case
>> right now.
>
> It was the case for me for x86 config, but you are right it is not the
> default case for arm.
>
>>
>> We will fix it.
>>
>>>
>>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
>>>> endif
>>>>
>>>
>>> <...>
>>>> +# library dependencies
>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>>>
>>> This dependeny doesn not looks correct, there is no folder like that.
>>
>> This is something even I need to understand. From the DEPDIRS what I
>> understood was that though it refers to a directory, it essentially
>> links libraries in build/lib/*.
>>
>> Further, somehow the development is deploying drivers/bus,
>> drivers/common and drivers/pool in lib/* under the name specified as
>> LIB in Makefile. My understanding was that it is expected behavior and
>> not special because of drivers folder.
>>
>> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
>> drivers/common/dpaa2/qbman code.
>>
>> In fact, I think, this might also one of the issues why a parallel
>> shared build fails for DPAA2 PMD (added in Cover letter).
>> The dependency graph cannot create a graph for drivers/common
>> as dependency for drivers/net or drivers/bus and hence parallel build
>> fails because of missing libraries which are being parallely compiled.
>
> DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> should point to the folder,
>
> Following line will cause "librte_eal" to be compiled before driver:
> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>
> So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> there is no folder like that.
>
>
> Somewhere in the history, with following commit, DEPDIRS-y gained a side
> effect, it has been used to set dynamic linking dependencies, to fix
> underlinking issue:
> bf5a46fa5972 ("mk: generate internal library dependencies")
>
> I guess you are having that line to benefit from this side effect, but
> this can be done with following more properly:
> LDLIBS += lib/librte_common_dpaa2_qbman
>
>
> To resolve the drivers/net to drivers/common dependency, following line
> in this Makefile should work:
> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
>
> This adds following, which will cause "drivers/common" compiled before
> any "drivers/net":
> LOCAL_DEPDIRS-drivers/net += drivers/common
Thanks for your suggestion. This is one thing, I am not yet able to fix.
Based on your suggestions:
e.g.
LDLIBS += -lrte_common_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
It does add entry in the ".depdirs"
./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
drivers/common
./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
drivers/common
However, we keep on getting:
LD librte_bus_fslmc.so.1.1
aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
directory
make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
>>
>>>
>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
>>>> +
>>>> +include $(RTE_SDK)/mk/rte.lib.mk
>>>
>>> <...>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 14:37 ` Hemant Agrawal
@ 2017-01-24 16:35 ` Ferruh Yigit
2017-01-24 17:28 ` Thomas Monjalon
1 sibling, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-24 16:35 UTC (permalink / raw)
To: Hemant Agrawal, Shreyansh Jain
Cc: dev, thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob
On 1/24/2017 2:37 PM, Hemant Agrawal wrote:
> On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
>> On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
>>> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
>>>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>>>> 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>
>>>>> ---
>>>> <...>
>>>>
>>>>> diff --git a/drivers/common/Makefile b/drivers/common/Makefile
>>>>> index b52931c..0bb75b5 100644
>>>>> --- a/drivers/common/Makefile
>>>>> +++ b/drivers/common/Makefile
>>>>> @@ -35,7 +35,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
>>>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
>>>>> endif
>>>>>
>>>>> -ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>>>> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
>>>>> +CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
>>>>> +endif
>>>>> +
>>>>> +ifneq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
>>>>
>>>> I guess this is a typo, but this prevents DPAA2_COMMON to be compiled !!
>>>
>>> It should be 'ifeq' rather than 'ifneq'.
>>
>>> And it will prevent COMMON
>>> compilation only if CONFIG_RTE_LIBRTE_FSLMC_BUS=n which is not the case
>>> right now.
>>
>> It was the case for me for x86 config, but you are right it is not the
>> default case for arm.
>>
>>>
>>> We will fix it.
>>>
>>>>
>>>>> CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
>>>>> endif
>>>>>
>>>>
>>>> <...>
>>>>> +# library dependencies
>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>>>>
>>>> This dependeny doesn not looks correct, there is no folder like that.
>>>
>>> This is something even I need to understand. From the DEPDIRS what I
>>> understood was that though it refers to a directory, it essentially
>>> links libraries in build/lib/*.
>>>
>>> Further, somehow the development is deploying drivers/bus,
>>> drivers/common and drivers/pool in lib/* under the name specified as
>>> LIB in Makefile. My understanding was that it is expected behavior and
>>> not special because of drivers folder.
>>>
>>> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
>>> drivers/common/dpaa2/qbman code.
>>>
>>> In fact, I think, this might also one of the issues why a parallel
>>> shared build fails for DPAA2 PMD (added in Cover letter).
>>> The dependency graph cannot create a graph for drivers/common
>>> as dependency for drivers/net or drivers/bus and hence parallel build
>>> fails because of missing libraries which are being parallely compiled.
>>
>> DEPDIRS-y is mainly to resolve dependencies for compilation order, and
>> should point to the folder,
>>
>> Following line will cause "librte_eal" to be compiled before driver:
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>
>> So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
>> there is no folder like that.
>>
>>
>> Somewhere in the history, with following commit, DEPDIRS-y gained a side
>> effect, it has been used to set dynamic linking dependencies, to fix
>> underlinking issue:
>> bf5a46fa5972 ("mk: generate internal library dependencies")
>>
>> I guess you are having that line to benefit from this side effect, but
>> this can be done with following more properly:
>> LDLIBS += lib/librte_common_dpaa2_qbman
>>
>>
>> To resolve the drivers/net to drivers/common dependency, following line
>> in this Makefile should work:
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
>>
>> This adds following, which will cause "drivers/common" compiled before
>> any "drivers/net":
>> LOCAL_DEPDIRS-drivers/net += drivers/common
>
> Thanks for your suggestion. This is one thing, I am not yet able to fix.
>
> Based on your suggestions:
> e.g.
> LDLIBS += -lrte_common_dpaa2_qbman
> DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
>
> It does add entry in the ".depdirs"
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> drivers/common
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> drivers/common
>
> However, we keep on getting:
> LD librte_bus_fslmc.so.1.1
> aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> directory
> make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
Can you please share the log with V=1, it may say more.
>
>>>
>>>>
>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
>>>>> +
>>>>> +include $(RTE_SDK)/mk/rte.lib.mk
>>>>
>>>> <...>
>>>>
>>>
>>
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 14:37 ` Hemant Agrawal
2017-01-24 16:35 ` Ferruh Yigit
@ 2017-01-24 17:28 ` Thomas Monjalon
2017-01-25 12:23 ` Neil Horman
2017-01-25 15:29 ` Ferruh Yigit
1 sibling, 2 replies; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-24 17:28 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Ferruh Yigit, Shreyansh Jain, dev, bruce.richardson,
john.mcnamara, jerin.jacob
2017-01-24 20:07, Hemant Agrawal:
> On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> >>>> +# library dependencies
> >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
> >>>
> >>> This dependeny doesn not looks correct, there is no folder like that.
> >>
> >> This is something even I need to understand. From the DEPDIRS what I
> >> understood was that though it refers to a directory, it essentially
> >> links libraries in build/lib/*.
> >>
> >> Further, somehow the development is deploying drivers/bus,
> >> drivers/common and drivers/pool in lib/* under the name specified as
> >> LIB in Makefile. My understanding was that it is expected behavior and
> >> not special because of drivers folder.
> >>
> >> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> >> drivers/common/dpaa2/qbman code.
> >>
> >> In fact, I think, this might also one of the issues why a parallel
> >> shared build fails for DPAA2 PMD (added in Cover letter).
> >> The dependency graph cannot create a graph for drivers/common
> >> as dependency for drivers/net or drivers/bus and hence parallel build
> >> fails because of missing libraries which are being parallely compiled.
> >
> > DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> > should point to the folder,
> >
> > Following line will cause "librte_eal" to be compiled before driver:
> > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> >
> > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > there is no folder like that.
> >
> >
> > Somewhere in the history, with following commit, DEPDIRS-y gained a side
> > effect, it has been used to set dynamic linking dependencies, to fix
> > underlinking issue:
> > bf5a46fa5972 ("mk: generate internal library dependencies")
> >
> > I guess you are having that line to benefit from this side effect, but
> > this can be done with following more properly:
> > LDLIBS += lib/librte_common_dpaa2_qbman
> >
> >
> > To resolve the drivers/net to drivers/common dependency, following line
> > in this Makefile should work:
> > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> >
> > This adds following, which will cause "drivers/common" compiled before
> > any "drivers/net":
> > LOCAL_DEPDIRS-drivers/net += drivers/common
>
> Thanks for your suggestion. This is one thing, I am not yet able to fix.
>
> Based on your suggestions:
> e.g.
> LDLIBS += -lrte_common_dpaa2_qbman
> DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
>
> It does add entry in the ".depdirs"
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> drivers/common
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> drivers/common
>
> However, we keep on getting:
> LD librte_bus_fslmc.so.1.1
> aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> directory
> make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
Probably because of:
# Translate DEPDIRS-y into LDLIBS
# Ignore (sub)directory dependencies which do not provide an actual library
_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
_LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
It shows one important thing: qbman is not a driver, it is a lib.
So drivers/common/dpaa2 should be handled differently.
Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
Solution 2: host your bus libs outside of DPDK
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 17:28 ` Thomas Monjalon
@ 2017-01-25 12:23 ` Neil Horman
2017-01-25 13:34 ` Shreyansh Jain
2017-01-25 15:29 ` Ferruh Yigit
1 sibling, 1 reply; 549+ messages in thread
From: Neil Horman @ 2017-01-25 12:23 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Hemant Agrawal, Ferruh Yigit, Shreyansh Jain, dev,
bruce.richardson, john.mcnamara, jerin.jacob
On Tue, Jan 24, 2017 at 06:28:59PM +0100, Thomas Monjalon wrote:
> 2017-01-24 20:07, Hemant Agrawal:
> > On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> > >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> > >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> > >>>> +# library dependencies
> > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
> > >>>
> > >>> This dependeny doesn not looks correct, there is no folder like that.
> > >>
> > >> This is something even I need to understand. From the DEPDIRS what I
> > >> understood was that though it refers to a directory, it essentially
> > >> links libraries in build/lib/*.
> > >>
> > >> Further, somehow the development is deploying drivers/bus,
> > >> drivers/common and drivers/pool in lib/* under the name specified as
> > >> LIB in Makefile. My understanding was that it is expected behavior and
> > >> not special because of drivers folder.
> > >>
> > >> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> > >> drivers/common/dpaa2/qbman code.
> > >>
> > >> In fact, I think, this might also one of the issues why a parallel
> > >> shared build fails for DPAA2 PMD (added in Cover letter).
> > >> The dependency graph cannot create a graph for drivers/common
> > >> as dependency for drivers/net or drivers/bus and hence parallel build
> > >> fails because of missing libraries which are being parallely compiled.
> > >
> > > DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> > > should point to the folder,
> > >
> > > Following line will cause "librte_eal" to be compiled before driver:
> > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > >
> > > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > > there is no folder like that.
> > >
> > >
> > > Somewhere in the history, with following commit, DEPDIRS-y gained a side
> > > effect, it has been used to set dynamic linking dependencies, to fix
> > > underlinking issue:
> > > bf5a46fa5972 ("mk: generate internal library dependencies")
> > >
> > > I guess you are having that line to benefit from this side effect, but
> > > this can be done with following more properly:
> > > LDLIBS += lib/librte_common_dpaa2_qbman
> > >
> > >
> > > To resolve the drivers/net to drivers/common dependency, following line
> > > in this Makefile should work:
> > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> > >
> > > This adds following, which will cause "drivers/common" compiled before
> > > any "drivers/net":
> > > LOCAL_DEPDIRS-drivers/net += drivers/common
> >
> > Thanks for your suggestion. This is one thing, I am not yet able to fix.
> >
> > Based on your suggestions:
> > e.g.
> > LDLIBS += -lrte_common_dpaa2_qbman
> > DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
> >
> > It does add entry in the ".depdirs"
> > ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> > drivers/common
> > ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> > ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> > ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> > drivers/common
> >
> > However, we keep on getting:
> > LD librte_bus_fslmc.so.1.1
> > aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> > directory
> > make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
>
> Probably because of:
>
> # Translate DEPDIRS-y into LDLIBS
> # Ignore (sub)directory dependencies which do not provide an actual library
> _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
>
> It shows one important thing: qbman is not a driver, it is a lib.
> So drivers/common/dpaa2 should be handled differently.
>
> Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> Solution 2: host your bus libs outside of DPDK
Please do not go with suggestion two, the more libraries get hosted outside of
the project, the less likely any sort of test/build/ongoing maintenence from the
community can be expected. If you're going to go with solution (2), then you
may as well host the entire PMD outside of the DPDK project, and thats more
undesireable.
Neil
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-25 12:23 ` Neil Horman
@ 2017-01-25 13:34 ` Shreyansh Jain
2017-01-25 13:47 ` Jerin Jacob
2017-01-25 15:07 ` Neil Horman
0 siblings, 2 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-25 13:34 UTC (permalink / raw)
To: Neil Horman, Thomas Monjalon
Cc: Hemant Agrawal, Ferruh Yigit, dev, bruce.richardson,
john.mcnamara, jerin.jacob
> -----Original Message-----
> From: Neil Horman [mailto:nhorman@tuxdriver.com]
> Sent: Wednesday, January 25, 2017 5:53 PM
> To: Thomas Monjalon <thomas.monjalon@6wind.com>
> Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Ferruh Yigit
> <ferruh.yigit@intel.com>; Shreyansh Jain <shreyansh.jain@nxp.com>;
> dev@dpdk.org; bruce.richardson@intel.com; john.mcnamara@intel.com;
> jerin.jacob@caviumnetworks.com
> Subject: Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw
> offloaded mempool
>
> On Tue, Jan 24, 2017 at 06:28:59PM +0100, Thomas Monjalon wrote:
> > 2017-01-24 20:07, Hemant Agrawal:
> > > On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > > > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> > > >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> > > >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> > > >>>> +# library dependencies
> > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) +=
> lib/librte_common_dpaa2_qbman
> > > >>>
> > > >>> This dependeny doesn not looks correct, there is no folder like that.
> > > >>
> > > >> This is something even I need to understand. From the DEPDIRS what I
> > > >> understood was that though it refers to a directory, it essentially
> > > >> links libraries in build/lib/*.
> > > >>
> > > >> Further, somehow the development is deploying drivers/bus,
> > > >> drivers/common and drivers/pool in lib/* under the name specified as
> > > >> LIB in Makefile. My understanding was that it is expected behavior and
> > > >> not special because of drivers folder.
> > > >>
> > > >> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> > > >> drivers/common/dpaa2/qbman code.
> > > >>
> > > >> In fact, I think, this might also one of the issues why a parallel
> > > >> shared build fails for DPAA2 PMD (added in Cover letter).
> > > >> The dependency graph cannot create a graph for drivers/common
> > > >> as dependency for drivers/net or drivers/bus and hence parallel build
> > > >> fails because of missing libraries which are being parallely compiled.
> > > >
> > > > DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> > > > should point to the folder,
> > > >
> > > > Following line will cause "librte_eal" to be compiled before driver:
> > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > >
> > > > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > > > there is no folder like that.
> > > >
> > > >
> > > > Somewhere in the history, with following commit, DEPDIRS-y gained a
> side
> > > > effect, it has been used to set dynamic linking dependencies, to fix
> > > > underlinking issue:
> > > > bf5a46fa5972 ("mk: generate internal library dependencies")
> > > >
> > > > I guess you are having that line to benefit from this side effect, but
> > > > this can be done with following more properly:
> > > > LDLIBS += lib/librte_common_dpaa2_qbman
> > > >
> > > >
> > > > To resolve the drivers/net to drivers/common dependency, following line
> > > > in this Makefile should work:
> > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> > > >
> > > > This adds following, which will cause "drivers/common" compiled before
> > > > any "drivers/net":
> > > > LOCAL_DEPDIRS-drivers/net += drivers/common
> > >
> > > Thanks for your suggestion. This is one thing, I am not yet able to fix.
> > >
> > > Based on your suggestions:
> > > e.g.
> > > LDLIBS += -lrte_common_dpaa2_qbman
> > > DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
> > >
> > > It does add entry in the ".depdirs"
> > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> > > drivers/common
> > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> > > drivers/common
> > >
> > > However, we keep on getting:
> > > LD librte_bus_fslmc.so.1.1
> > > aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> > > directory
> > > make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
> >
> > Probably because of:
> >
> > # Translate DEPDIRS-y into LDLIBS
> > # Ignore (sub)directory dependencies which do not provide an actual library
> > _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> > _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> > _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> > LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
> >
> > It shows one important thing: qbman is not a driver, it is a lib.
> > So drivers/common/dpaa2 should be handled differently.
> >
> > Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> > Solution 2: host your bus libs outside of DPDK
> Please do not go with suggestion two, the more libraries get hosted outside
> of
> the project, the less likely any sort of test/build/ongoing maintenence from
> the
> community can be expected. If you're going to go with solution (2), then you
> may as well host the entire PMD outside of the DPDK project, and thats more
> undesireable.
Agree with you. Hosting a part of PMD (or PMD itself) outside of DPDK is not
a preferred way for me as well. Besides being non-user-friendly, this has
obvious disadvantage of a fragmented software which will quickly become
difficult to manage/maintain.
But, renaming so many variables also is not an easy choice (assuming
that the suggestion from you for MAP_STATIC_SYMBOL is not in place - still
investigating on that).
Merging everything together has already been ruled out in initial RFC
Discussions.
>
> Neil
>
> >
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-25 13:34 ` Shreyansh Jain
@ 2017-01-25 13:47 ` Jerin Jacob
2017-01-25 15:07 ` Neil Horman
1 sibling, 0 replies; 549+ messages in thread
From: Jerin Jacob @ 2017-01-25 13:47 UTC (permalink / raw)
To: Shreyansh Jain
Cc: Neil Horman, Thomas Monjalon, Hemant Agrawal, Ferruh Yigit, dev,
bruce.richardson, john.mcnamara
On Wed, Jan 25, 2017 at 01:34:47PM +0000, Shreyansh Jain wrote:
>
>
> > -----Original Message-----
> > From: Neil Horman [mailto:nhorman@tuxdriver.com]
> > Sent: Wednesday, January 25, 2017 5:53 PM
> > To: Thomas Monjalon <thomas.monjalon@6wind.com>
> > Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Ferruh Yigit
> > <ferruh.yigit@intel.com>; Shreyansh Jain <shreyansh.jain@nxp.com>;
> > dev@dpdk.org; bruce.richardson@intel.com; john.mcnamara@intel.com;
> > jerin.jacob@caviumnetworks.com
> > Subject: Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw
> > offloaded mempool
> >
> > On Tue, Jan 24, 2017 at 06:28:59PM +0100, Thomas Monjalon wrote:
> > > 2017-01-24 20:07, Hemant Agrawal:
> > > > On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > > > > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> > > > >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> > > > >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> > > > >>>> +# library dependencies
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) +=
> > lib/librte_common_dpaa2_qbman
> > > > >>>
> > > > >>> This dependeny doesn not looks correct, there is no folder like that.
> > > > >>
> > > > >> This is something even I need to understand. From the DEPDIRS what I
> > > > >> understood was that though it refers to a directory, it essentially
> > > > >> links libraries in build/lib/*.
> > > > >>
> > > > >> Further, somehow the development is deploying drivers/bus,
> > > > >> drivers/common and drivers/pool in lib/* under the name specified as
> > > > >> LIB in Makefile. My understanding was that it is expected behavior and
> > > > >> not special because of drivers folder.
> > > > >>
> > > > >> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> > > > >> drivers/common/dpaa2/qbman code.
> > > > >>
> > > > >> In fact, I think, this might also one of the issues why a parallel
> > > > >> shared build fails for DPAA2 PMD (added in Cover letter).
> > > > >> The dependency graph cannot create a graph for drivers/common
> > > > >> as dependency for drivers/net or drivers/bus and hence parallel build
> > > > >> fails because of missing libraries which are being parallely compiled.
> > > > >
> > > > > DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> > > > > should point to the folder,
> > > > >
> > > > > Following line will cause "librte_eal" to be compiled before driver:
> > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > >
> > > > > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > > > > there is no folder like that.
> > > > >
> > > > >
> > > > > Somewhere in the history, with following commit, DEPDIRS-y gained a
> > side
> > > > > effect, it has been used to set dynamic linking dependencies, to fix
> > > > > underlinking issue:
> > > > > bf5a46fa5972 ("mk: generate internal library dependencies")
> > > > >
> > > > > I guess you are having that line to benefit from this side effect, but
> > > > > this can be done with following more properly:
> > > > > LDLIBS += lib/librte_common_dpaa2_qbman
> > > > >
> > > > >
> > > > > To resolve the drivers/net to drivers/common dependency, following line
> > > > > in this Makefile should work:
> > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> > > > >
> > > > > This adds following, which will cause "drivers/common" compiled before
> > > > > any "drivers/net":
> > > > > LOCAL_DEPDIRS-drivers/net += drivers/common
> > > >
> > > > Thanks for your suggestion. This is one thing, I am not yet able to fix.
> > > >
> > > > Based on your suggestions:
> > > > e.g.
> > > > LDLIBS += -lrte_common_dpaa2_qbman
> > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
> > > >
> > > > It does add entry in the ".depdirs"
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> > > > drivers/common
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> > > > drivers/common
> > > >
> > > > However, we keep on getting:
> > > > LD librte_bus_fslmc.so.1.1
> > > > aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> > > > directory
> > > > make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
> > >
> > > Probably because of:
> > >
> > > # Translate DEPDIRS-y into LDLIBS
> > > # Ignore (sub)directory dependencies which do not provide an actual library
> > > _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> > > _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> > > _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> > > LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
> > >
> > > It shows one important thing: qbman is not a driver, it is a lib.
> > > So drivers/common/dpaa2 should be handled differently.
> > >
> > > Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> > > Solution 2: host your bus libs outside of DPDK
> > Please do not go with suggestion two, the more libraries get hosted outside
> > of
> > the project, the less likely any sort of test/build/ongoing maintenence from
> > the
> > community can be expected. If you're going to go with solution (2), then you
> > may as well host the entire PMD outside of the DPDK project, and thats more
> > undesireable.
>
> Agree with you. Hosting a part of PMD (or PMD itself) outside of DPDK is not
> a preferred way for me as well. Besides being non-user-friendly, this has
> obvious disadvantage of a fragmented software which will quickly become
> difficult to manage/maintain.
+1
If NXP drivers are only the consumers for the common code. Then I think,
there is no harm in exposing them as non rte_ namespace.
>
> But, renaming so many variables also is not an easy choice (assuming
> that the suggestion from you for MAP_STATIC_SYMBOL is not in place - still
> investigating on that).
> Merging everything together has already been ruled out in initial RFC
> Discussions.
>
> >
> > Neil
> >
> > >
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-25 13:34 ` Shreyansh Jain
2017-01-25 13:47 ` Jerin Jacob
@ 2017-01-25 15:07 ` Neil Horman
2017-01-26 12:05 ` Shreyansh Jain
1 sibling, 1 reply; 549+ messages in thread
From: Neil Horman @ 2017-01-25 15:07 UTC (permalink / raw)
To: Shreyansh Jain
Cc: Thomas Monjalon, Hemant Agrawal, Ferruh Yigit, dev,
bruce.richardson, john.mcnamara, jerin.jacob
On Wed, Jan 25, 2017 at 01:34:47PM +0000, Shreyansh Jain wrote:
>
>
> > -----Original Message-----
> > From: Neil Horman [mailto:nhorman@tuxdriver.com]
> > Sent: Wednesday, January 25, 2017 5:53 PM
> > To: Thomas Monjalon <thomas.monjalon@6wind.com>
> > Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Ferruh Yigit
> > <ferruh.yigit@intel.com>; Shreyansh Jain <shreyansh.jain@nxp.com>;
> > dev@dpdk.org; bruce.richardson@intel.com; john.mcnamara@intel.com;
> > jerin.jacob@caviumnetworks.com
> > Subject: Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw
> > offloaded mempool
> >
> > On Tue, Jan 24, 2017 at 06:28:59PM +0100, Thomas Monjalon wrote:
> > > 2017-01-24 20:07, Hemant Agrawal:
> > > > On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > > > > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> > > > >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> > > > >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> > > > >>>> +# library dependencies
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) +=
> > lib/librte_common_dpaa2_qbman
> > > > >>>
> > > > >>> This dependeny doesn not looks correct, there is no folder like that.
> > > > >>
> > > > >> This is something even I need to understand. From the DEPDIRS what I
> > > > >> understood was that though it refers to a directory, it essentially
> > > > >> links libraries in build/lib/*.
> > > > >>
> > > > >> Further, somehow the development is deploying drivers/bus,
> > > > >> drivers/common and drivers/pool in lib/* under the name specified as
> > > > >> LIB in Makefile. My understanding was that it is expected behavior and
> > > > >> not special because of drivers folder.
> > > > >>
> > > > >> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
> > > > >> drivers/common/dpaa2/qbman code.
> > > > >>
> > > > >> In fact, I think, this might also one of the issues why a parallel
> > > > >> shared build fails for DPAA2 PMD (added in Cover letter).
> > > > >> The dependency graph cannot create a graph for drivers/common
> > > > >> as dependency for drivers/net or drivers/bus and hence parallel build
> > > > >> fails because of missing libraries which are being parallely compiled.
> > > > >
> > > > > DEPDIRS-y is mainly to resolve dependencies for compilation order, and
> > > > > should point to the folder,
> > > > >
> > > > > Following line will cause "librte_eal" to be compiled before driver:
> > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > >
> > > > > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > > > > there is no folder like that.
> > > > >
> > > > >
> > > > > Somewhere in the history, with following commit, DEPDIRS-y gained a
> > side
> > > > > effect, it has been used to set dynamic linking dependencies, to fix
> > > > > underlinking issue:
> > > > > bf5a46fa5972 ("mk: generate internal library dependencies")
> > > > >
> > > > > I guess you are having that line to benefit from this side effect, but
> > > > > this can be done with following more properly:
> > > > > LDLIBS += lib/librte_common_dpaa2_qbman
> > > > >
> > > > >
> > > > > To resolve the drivers/net to drivers/common dependency, following line
> > > > > in this Makefile should work:
> > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> > > > >
> > > > > This adds following, which will cause "drivers/common" compiled before
> > > > > any "drivers/net":
> > > > > LOCAL_DEPDIRS-drivers/net += drivers/common
> > > >
> > > > Thanks for your suggestion. This is one thing, I am not yet able to fix.
> > > >
> > > > Based on your suggestions:
> > > > e.g.
> > > > LDLIBS += -lrte_common_dpaa2_qbman
> > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
> > > >
> > > > It does add entry in the ".depdirs"
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> > > > drivers/common
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> > > > drivers/common
> > > >
> > > > However, we keep on getting:
> > > > LD librte_bus_fslmc.so.1.1
> > > > aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> > > > directory
> > > > make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
> > >
> > > Probably because of:
> > >
> > > # Translate DEPDIRS-y into LDLIBS
> > > # Ignore (sub)directory dependencies which do not provide an actual library
> > > _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> > > _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> > > _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> > > LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
> > >
> > > It shows one important thing: qbman is not a driver, it is a lib.
> > > So drivers/common/dpaa2 should be handled differently.
> > >
> > > Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> > > Solution 2: host your bus libs outside of DPDK
> > Please do not go with suggestion two, the more libraries get hosted outside
> > of
> > the project, the less likely any sort of test/build/ongoing maintenence from
> > the
> > community can be expected. If you're going to go with solution (2), then you
> > may as well host the entire PMD outside of the DPDK project, and thats more
> > undesireable.
>
> Agree with you. Hosting a part of PMD (or PMD itself) outside of DPDK is not
> a preferred way for me as well. Besides being non-user-friendly, this has
> obvious disadvantage of a fragmented software which will quickly become
> difficult to manage/maintain.
>
> But, renaming so many variables also is not an easy choice (assuming
> that the suggestion from you for MAP_STATIC_SYMBOL is not in place - still
> investigating on that).
I'm not sure what you mean by this, MAP_STATIC_SYMBOL is an available macro in
dpdk already, and you can ifndef...define...endif it to a no-op so that you can
keep the usage outside of dpdk.
Neil
> Merging everything together has already been ruled out in initial RFC
> Discussions.
>
> >
> > Neil
> >
> > >
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-25 15:07 ` Neil Horman
@ 2017-01-26 12:05 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-01-26 12:05 UTC (permalink / raw)
To: Neil Horman
Cc: Thomas Monjalon, Hemant Agrawal, Ferruh Yigit, dev,
bruce.richardson, john.mcnamara, jerin.jacob
Hello Neil,
> -----Original Message-----
> From: Neil Horman [mailto:nhorman@tuxdriver.com]
> Sent: Wednesday, January 25, 2017 8:37 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>; Ferruh Yigit <ferruh.yigit@intel.com>;
> dev@dpdk.org; bruce.richardson@intel.com; john.mcnamara@intel.com;
> jerin.jacob@caviumnetworks.com
> Subject: Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw
> offloaded mempool
>
> On Wed, Jan 25, 2017 at 01:34:47PM +0000, Shreyansh Jain wrote:
> >
> >
> > > -----Original Message-----
> > > From: Neil Horman [mailto:nhorman@tuxdriver.com]
> > > Sent: Wednesday, January 25, 2017 5:53 PM
> > > To: Thomas Monjalon <thomas.monjalon@6wind.com>
> > > Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Ferruh Yigit
> > > <ferruh.yigit@intel.com>; Shreyansh Jain <shreyansh.jain@nxp.com>;
> > > dev@dpdk.org; bruce.richardson@intel.com; john.mcnamara@intel.com;
> > > jerin.jacob@caviumnetworks.com
> > > Subject: Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw
> > > offloaded mempool
> > >
> > > On Tue, Jan 24, 2017 at 06:28:59PM +0100, Thomas Monjalon wrote:
> > > > 2017-01-24 20:07, Hemant Agrawal:
> > > > > On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
> > > > > > On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
> > > > > >> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
> > > > > >>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> > > > > >>>> +# library dependencies
> > > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
> > > > > >>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) +=
> > > lib/librte_common_dpaa2_qbman
> > > > > >>>
> > > > > >>> This dependeny doesn not looks correct, there is no folder like
> that.
> > > > > >>
> > > > > >> This is something even I need to understand. From the DEPDIRS what
> I
> > > > > >> understood was that though it refers to a directory, it
> essentially
> > > > > >> links libraries in build/lib/*.
> > > > > >>
> > > > > >> Further, somehow the development is deploying drivers/bus,
> > > > > >> drivers/common and drivers/pool in lib/* under the name specified
> as
> > > > > >> LIB in Makefile. My understanding was that it is expected behavior
> and
> > > > > >> not special because of drivers folder.
> > > > > >>
> > > > > >> Thus, above line only links lib/librte_common_dpaa2_qbman
> generated by
> > > > > >> drivers/common/dpaa2/qbman code.
> > > > > >>
> > > > > >> In fact, I think, this might also one of the issues why a parallel
> > > > > >> shared build fails for DPAA2 PMD (added in Cover letter).
> > > > > >> The dependency graph cannot create a graph for drivers/common
> > > > > >> as dependency for drivers/net or drivers/bus and hence parallel
> build
> > > > > >> fails because of missing libraries which are being parallely
> compiled.
> > > > > >
> > > > > > DEPDIRS-y is mainly to resolve dependencies for compilation order,
> and
> > > > > > should point to the folder,
> > > > > >
> > > > > > Following line will cause "librte_eal" to be compiled before
> driver:
> > > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
> > > > > >
> > > > > > So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
> > > > > > there is no folder like that.
> > > > > >
> > > > > >
> > > > > > Somewhere in the history, with following commit, DEPDIRS-y gained a
> > > side
> > > > > > effect, it has been used to set dynamic linking dependencies, to
> fix
> > > > > > underlinking issue:
> > > > > > bf5a46fa5972 ("mk: generate internal library dependencies")
> > > > > >
> > > > > > I guess you are having that line to benefit from this side effect,
> but
> > > > > > this can be done with following more properly:
> > > > > > LDLIBS += lib/librte_common_dpaa2_qbman
> > > > > >
> > > > > >
> > > > > > To resolve the drivers/net to drivers/common dependency, following
> line
> > > > > > in this Makefile should work:
> > > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
> > > > > >
> > > > > > This adds following, which will cause "drivers/common" compiled
> before
> > > > > > any "drivers/net":
> > > > > > LOCAL_DEPDIRS-drivers/net += drivers/common
> > > > >
> > > > > Thanks for your suggestion. This is one thing, I am not yet able to
> fix.
> > > > >
> > > > > Based on your suggestions:
> > > > > e.g.
> > > > > LDLIBS += -lrte_common_dpaa2_qbman
> > > > > DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
> > > > >
> > > > > It does add entry in the ".depdirs"
> > > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
> > > > > drivers/common
> > > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
> > > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
> > > > > ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
> > > > > drivers/common
> > > > >
> > > > > However, we keep on getting:
> > > > > LD librte_bus_fslmc.so.1.1
> > > > > aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
> > > > > directory
> > > > > make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
> > > >
> > > > Probably because of:
> > > >
> > > > # Translate DEPDIRS-y into LDLIBS
> > > > # Ignore (sub)directory dependencies which do not provide an actual
> library
> > > > _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> > > > _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> > > > _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> > > > LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
> > > >
> > > > It shows one important thing: qbman is not a driver, it is a lib.
> > > > So drivers/common/dpaa2 should be handled differently.
> > > >
> > > > Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> > > > Solution 2: host your bus libs outside of DPDK
> > > Please do not go with suggestion two, the more libraries get hosted
> outside
> > > of
> > > the project, the less likely any sort of test/build/ongoing maintenence
> from
> > > the
> > > community can be expected. If you're going to go with solution (2), then
> you
> > > may as well host the entire PMD outside of the DPDK project, and thats
> more
> > > undesireable.
> >
> > Agree with you. Hosting a part of PMD (or PMD itself) outside of DPDK is
> not
> > a preferred way for me as well. Besides being non-user-friendly, this has
> > obvious disadvantage of a fragmented software which will quickly become
> > difficult to manage/maintain.
> >
> > But, renaming so many variables also is not an easy choice (assuming
> > that the suggestion from you for MAP_STATIC_SYMBOL is not in place - still
> > investigating on that).
> I'm not sure what you mean by this, MAP_STATIC_SYMBOL is an available macro
> in
> dpdk already, and you can ifndef...define...endif it to a no-op so that you
> can
> keep the usage outside of dpdk.
I only meant that as of writing the last mail I haven't had yet investigated/
tried that way. That is all.
I am not doubting this method (at least not until I try and reach some
roadblock).
>
> Neil
>
> > Merging everything together has already been ruled out in initial RFC
> > Discussions.
> >
> > >
> > > Neil
> > >
> > > >
> >
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-24 17:28 ` Thomas Monjalon
2017-01-25 12:23 ` Neil Horman
@ 2017-01-25 15:29 ` Ferruh Yigit
2017-01-25 15:33 ` Ferruh Yigit
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-25 15:29 UTC (permalink / raw)
To: Thomas Monjalon, Hemant Agrawal
Cc: Shreyansh Jain, dev, bruce.richardson, john.mcnamara, jerin.jacob
On 1/24/2017 5:28 PM, Thomas Monjalon wrote:
> 2017-01-24 20:07, Hemant Agrawal:
>> On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
>>> On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
>>>> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
>>>>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>>>>> +# library dependencies
>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>>>>>
>>>>> This dependeny doesn not looks correct, there is no folder like that.
>>>>
>>>> This is something even I need to understand. From the DEPDIRS what I
>>>> understood was that though it refers to a directory, it essentially
>>>> links libraries in build/lib/*.
>>>>
>>>> Further, somehow the development is deploying drivers/bus,
>>>> drivers/common and drivers/pool in lib/* under the name specified as
>>>> LIB in Makefile. My understanding was that it is expected behavior and
>>>> not special because of drivers folder.
>>>>
>>>> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
>>>> drivers/common/dpaa2/qbman code.
>>>>
>>>> In fact, I think, this might also one of the issues why a parallel
>>>> shared build fails for DPAA2 PMD (added in Cover letter).
>>>> The dependency graph cannot create a graph for drivers/common
>>>> as dependency for drivers/net or drivers/bus and hence parallel build
>>>> fails because of missing libraries which are being parallely compiled.
>>>
>>> DEPDIRS-y is mainly to resolve dependencies for compilation order, and
>>> should point to the folder,
>>>
>>> Following line will cause "librte_eal" to be compiled before driver:
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>
>>> So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
>>> there is no folder like that.
>>>
>>>
>>> Somewhere in the history, with following commit, DEPDIRS-y gained a side
>>> effect, it has been used to set dynamic linking dependencies, to fix
>>> underlinking issue:
>>> bf5a46fa5972 ("mk: generate internal library dependencies")
>>>
>>> I guess you are having that line to benefit from this side effect, but
>>> this can be done with following more properly:
>>> LDLIBS += lib/librte_common_dpaa2_qbman
>>>
>>>
>>> To resolve the drivers/net to drivers/common dependency, following line
>>> in this Makefile should work:
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
>>>
>>> This adds following, which will cause "drivers/common" compiled before
>>> any "drivers/net":
>>> LOCAL_DEPDIRS-drivers/net += drivers/common
>>
>> Thanks for your suggestion. This is one thing, I am not yet able to fix.
>>
>> Based on your suggestions:
>> e.g.
>> LDLIBS += -lrte_common_dpaa2_qbman
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
>>
>> It does add entry in the ".depdirs"
>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
>> drivers/common
>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
>> drivers/common
>>
>> However, we keep on getting:
>> LD librte_bus_fslmc.so.1.1
>> aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
>> directory
>> make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
>
> Probably because of:
>
> # Translate DEPDIRS-y into LDLIBS
> # Ignore (sub)directory dependencies which do not provide an actual library
> _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
>
> It shows one important thing: qbman is not a driver, it is a lib.
> So drivers/common/dpaa2 should be handled differently.
>
> Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
> Solution 2: host your bus libs outside of DPDK
>
For solution 1, following [1] seems working, "drivers/%" preferred
against "drivers/common/%" because "drivers/bus/%" has same issue. And
as far as I can see dpaa2 is the only driver dependency in lib folder.
[1]
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 33a5f5a..ac4df9a 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -79,7 +79,7 @@ endif
# Translate DEPDIRS-y into LDLIBS
# Ignore (sub)directory dependencies which do not provide an actual library
-_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
+_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat drivers/%
_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
_LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool
2017-01-25 15:29 ` Ferruh Yigit
@ 2017-01-25 15:33 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-25 15:33 UTC (permalink / raw)
To: Thomas Monjalon, Hemant Agrawal
Cc: Shreyansh Jain, dev, bruce.richardson, john.mcnamara, jerin.jacob
On 1/25/2017 3:29 PM, Ferruh Yigit wrote:
> On 1/24/2017 5:28 PM, Thomas Monjalon wrote:
>> 2017-01-24 20:07, Hemant Agrawal:
>>> On 1/24/2017 4:19 PM, Ferruh Yigit wrote:
>>>> On 1/24/2017 9:12 AM, Shreyansh Jain wrote:
>>>>> On Monday 23 January 2017 11:04 PM, Ferruh Yigit wrote:
>>>>>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>>>>>> +# library dependencies
>>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
>>>>>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
>>>>>>
>>>>>> This dependeny doesn not looks correct, there is no folder like that.
>>>>>
>>>>> This is something even I need to understand. From the DEPDIRS what I
>>>>> understood was that though it refers to a directory, it essentially
>>>>> links libraries in build/lib/*.
>>>>>
>>>>> Further, somehow the development is deploying drivers/bus,
>>>>> drivers/common and drivers/pool in lib/* under the name specified as
>>>>> LIB in Makefile. My understanding was that it is expected behavior and
>>>>> not special because of drivers folder.
>>>>>
>>>>> Thus, above line only links lib/librte_common_dpaa2_qbman generated by
>>>>> drivers/common/dpaa2/qbman code.
>>>>>
>>>>> In fact, I think, this might also one of the issues why a parallel
>>>>> shared build fails for DPAA2 PMD (added in Cover letter).
>>>>> The dependency graph cannot create a graph for drivers/common
>>>>> as dependency for drivers/net or drivers/bus and hence parallel build
>>>>> fails because of missing libraries which are being parallely compiled.
>>>>
>>>> DEPDIRS-y is mainly to resolve dependencies for compilation order, and
>>>> should point to the folder,
>>>>
>>>> Following line will cause "librte_eal" to be compiled before driver:
>>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
>>>>
>>>> So "lib/librte_common_dpaa2_qbman" does not makes more sense, since
>>>> there is no folder like that.
>>>>
>>>>
>>>> Somewhere in the history, with following commit, DEPDIRS-y gained a side
>>>> effect, it has been used to set dynamic linking dependencies, to fix
>>>> underlinking issue:
>>>> bf5a46fa5972 ("mk: generate internal library dependencies")
>>>>
>>>> I guess you are having that line to benefit from this side effect, but
>>>> this can be done with following more properly:
>>>> LDLIBS += lib/librte_common_dpaa2_qbman
>>>>
>>>>
>>>> To resolve the drivers/net to drivers/common dependency, following line
>>>> in this Makefile should work:
>>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
>>>>
>>>> This adds following, which will cause "drivers/common" compiled before
>>>> any "drivers/net":
>>>> LOCAL_DEPDIRS-drivers/net += drivers/common
>>>
>>> Thanks for your suggestion. This is one thing, I am not yet able to fix.
>>>
>>> Based on your suggestions:
>>> e.g.
>>> LDLIBS += -lrte_common_dpaa2_qbman
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
>>>
>>> It does add entry in the ".depdirs"
>>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:168:LOCAL_DEPDIRS-drivers/bus +=
>>> drivers/common
>>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:170:LOCAL_DEPDIRS-drivers += lib
>>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:172:LOCAL_DEPDIRS-drivers += lib
>>> ./arm64-dpaa2-linuxapp-gcc/.depdirs:174:LOCAL_DEPDIRS-drivers/pool +=
>>> drivers/common
>>>
>>> However, we keep on getting:
>>> LD librte_bus_fslmc.so.1.1
>>> aarch64-linux-gnu-gcc: error: drivers/common/dpaa2: No such file or
>>> directory
>>> make[6]: *** [librte_bus_fslmc.so.1.1] Error 1
>>
>> Probably because of:
>>
>> # Translate DEPDIRS-y into LDLIBS
>> # Ignore (sub)directory dependencies which do not provide an actual library
>> _IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
>> _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
>> _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
>> LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
>>
>> It shows one important thing: qbman is not a driver, it is a lib.
>> So drivers/common/dpaa2 should be handled differently.
>>
>> Solution 1: tweak mk/rte.lib.mk for directories in drivers/common/
>> Solution 2: host your bus libs outside of DPDK
>>
>
> For solution 1, following [1] seems working, "drivers/%" preferred
> against "drivers/common/%" because "drivers/bus/%" has same issue. And
> as far as I can see dpaa2 is the only driver dependency in lib folder.
>
> [1]
> diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
> index 33a5f5a..ac4df9a 100644
> --- a/mk/rte.lib.mk
> +++ b/mk/rte.lib.mk
> @@ -79,7 +79,7 @@ endif
>
> # Translate DEPDIRS-y into LDLIBS
> # Ignore (sub)directory dependencies which do not provide an actual library
> -_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
> +_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat drivers/%
> _DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
> _LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
> LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
>
Hi Hemant,
Overall, shared compilation with -jN is working fine for me with below
patch, putting here as reference:
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 263c4fd..405fbaa 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -74,6 +74,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
-DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_common_dpaa2_qbman
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += drivers/common/dpaa2
+
+LDLIBS += -lrte_common_dpaa2_qbman
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index d52fa39..5b1613c 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -65,8 +65,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool
lib/librte_mbuf
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pool_dpaa2
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/pool/dpaa2
+
+LDLIBS += -lrte_common_dpaa2_qbman
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_pool_dpaa2
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/pool/dpaa2/Makefile b/drivers/pool/dpaa2/Makefile
index 69e1bb4..6b27cd5 100644
--- a/drivers/pool/dpaa2/Makefile
+++ b/drivers/pool/dpaa2/Makefile
@@ -65,7 +65,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) +=
dpaa2_hw_mempool.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_common_dpaa2_qbman
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_bus_fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += drivers/common/dpaa2
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += drivers/bus/fslmc
+
+
+LDLIBS += -lrte_common_dpaa2_qbman
+LDLIBS += -lrte_bus_fslmc
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 33a5f5a..ac4df9a 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -79,7 +79,7 @@ endif
# Translate DEPDIRS-y into LDLIBS
# Ignore (sub)directory dependencies which do not provide an actual library
-_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
+_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat drivers/%
_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
_LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (15 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 16/33] drivers/pool/dpaa2: adding hw offloaded mempool Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 18/33] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (18 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 45 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 3 ++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
3 files changed, 49 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index dd6de4c..bd1f643 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index 682f3fa..b1a1b8f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -56,5 +56,8 @@ 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);
+
#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 028f55e..4a8f478 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,7 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
dpaa2_free_dpbp_dev;
dpbp_disable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 18/33] net/dpaa2: adding eth ops to dpaa2
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (16 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 17/33] drivers/common/dpaa2: dpio routine to affine to crypto threads Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 17:35 ` Ferruh Yigit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 19/33] net/dpaa2: add rss flow distribution Hemant Agrawal
` (17 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++
drivers/net/dpaa2/Makefile | 3 +
drivers/net/dpaa2/dpaa2_ethdev.c | 412 +++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
5 files changed, 450 insertions(+), 1 deletion(-)
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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index ad2847f..42c5517 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -79,6 +82,23 @@ struct dpaa2_dpbp_dev {
uint32_t dpbp_id; /*HW ID for DPBP object */
};
+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 *(*rte_mcp_ptr_list);
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 6e0396a..5fb5f67 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -46,6 +46,8 @@ 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
@@ -59,6 +61,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index ead6a2c..df16159 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,442 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 18/33] net/dpaa2: adding eth ops to dpaa2
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 18/33] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-01-23 17:35 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:35 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> static int
> dpaa2_dev_init(struct rte_eth_dev *eth_dev)
> {
<...>
> + eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
> + eth_dev->data->nb_tx_queues = priv->nb_tx_queues;
No need to assign these during init(), app should set these via
rte_eth_dev_configure() API.
> +
> + priv->hw = dpni_dev;
> + priv->hw_id = hw_id;
> + priv->flags = 0;
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 19/33] net/dpaa2: add rss flow distribution
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (17 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 18/33] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 20/33] net/dpaa2: configure mac address at init Hemant Agrawal
` (16 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 5fb5f67..7d62f1e 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 df16159..87f7640 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 20/33] net/dpaa2: configure mac address at init
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (18 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 19/33] net/dpaa2: add rss flow distribution Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 21/33] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (15 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 87f7640..979dba4 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -446,6 +447,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);
@@ -454,6 +458,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 = rte_dpaa2_pmd.driver.name;
@@ -492,6 +515,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 21/33] net/dpaa2: attach the buffer pool to dpni
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (19 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 20/33] net/dpaa2: configure mac address at init Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload Hemant Agrawal
` (14 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_pvt.h | 10 ++++++
drivers/net/dpaa2/Makefile | 3 ++
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, 138 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 42c5517..8efac2d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 7d62f1e..fadabb5 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -62,7 +63,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
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 979dba4..6de571a 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -477,6 +490,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (20 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 21/33] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 17:35 ` Ferruh Yigit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 23/33] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (13 subsequent siblings)
35 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 6 +++
drivers/net/dpaa2/Makefile | 2 +-
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++--
4 files changed, 77 insertions(+), 5 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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 8efac2d..1af93a5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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/Makefile b/drivers/net/dpaa2/Makefile
index fadabb5..0e59203 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -66,6 +66,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
-DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pool_dpaa2
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 6de571a..2298246 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload Hemant Agrawal
@ 2017-01-23 17:35 ` Ferruh Yigit
2017-01-24 10:45 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:35 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -66,6 +66,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
> -DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pool_dpaa2
I understand these are added since DEPDIRS converted to LDLIBS, but this
does not looks right, since these variables mainly dependency solving
and the value provided is not correct for DEPDIRS.
Did you tried adding as "LDLIBS += xx", not tested, but may work.
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 6de571a..2298246 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -68,7 +68,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;
Is there capabilities always enabled for all devices this driver
support? Or should these be read from some device registers?
> + 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;
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload
2017-01-23 17:35 ` Ferruh Yigit
@ 2017-01-24 10:45 ` Hemant Agrawal
2017-01-24 10:51 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-24 10:45 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:05 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
> <...>
>> --- a/drivers/net/dpaa2/Makefile
>> +++ b/drivers/net/dpaa2/Makefile
>> @@ -66,6 +66,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
>> -DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pool_dpaa2
>
> I understand these are added since DEPDIRS converted to LDLIBS, but this
> does not looks right, since these variables mainly dependency solving
> and the value provided is not correct for DEPDIRS.
>
> Did you tried adding as "LDLIBS += xx", not tested, but may work.
>
Our intention was to create dependency to help in parallel build in case
of shared library. "LDLIBS += xx" also work, but we are still not able
to create inter driver directory dependency for parallel build.
We may need your help in understanding the change required in depdir
script to support directories within "driver".
>>
>> include $(RTE_SDK)/mk/rte.lib.mk
>> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
>> index 6de571a..2298246 100644
>> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
>> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
>> @@ -68,7 +68,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;
>
> Is there capabilities always enabled for all devices this driver
> support? Or should these be read from some device registers?
>
Capabilities are always enabled for all devices (MC DPNI object in this
case)
>> + 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;
> <...>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload
2017-01-24 10:45 ` Hemant Agrawal
@ 2017-01-24 10:51 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-24 10:51 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/24/2017 10:45 AM, Hemant Agrawal wrote:
> On 1/23/2017 11:05 PM, Ferruh Yigit wrote:
>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> ---
>> <...>
>>> --- a/drivers/net/dpaa2/Makefile
>>> +++ b/drivers/net/dpaa2/Makefile
>>> @@ -66,6 +66,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_common_dpaa2_qbman
>>> DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_bus_fslmc
>>> -DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pmd_dpaa2_pool
>>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_pool_dpaa2
>>
>> I understand these are added since DEPDIRS converted to LDLIBS, but this
>> does not looks right, since these variables mainly dependency solving
>> and the value provided is not correct for DEPDIRS.
>>
>> Did you tried adding as "LDLIBS += xx", not tested, but may work.
>>
>
> Our intention was to create dependency to help in parallel build in case
> of shared library. "LDLIBS += xx" also work, but we are still not able
> to create inter driver directory dependency for parallel build.
>
>
> We may need your help in understanding the change required in depdir
> script to support directories within "driver".
>
>>>
>>> include $(RTE_SDK)/mk/rte.lib.mk
>>> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
>>> index 6de571a..2298246 100644
>>> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
>>> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
>>> @@ -68,7 +68,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;
>>
>> Is there capabilities always enabled for all devices this driver
>> support? Or should these be read from some device registers?
>>
> Capabilities are always enabled for all devices (MC DPNI object in this
> case)
Thanks for the clarification, is it same for the speed capabilities?
>
>>> + 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;
>> <...>
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 23/33] net/dpaa2: add support for promiscuous mode
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (21 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 22/33] net/dpaa2: add support for l3 and l4 checksum offload Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 24/33] net/dpaa2: add mtu config support Hemant Agrawal
` (12 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 2298246..df78f6c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 24/33] net/dpaa2: add mtu config support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (22 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 23/33] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 25/33] net/dpaa2: add packet rx and tx support Hemant Agrawal
` (11 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1af93a5..2a8d9e5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 df78f6c..7e64e60 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 25/33] net/dpaa2: add packet rx and tx support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (23 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 24/33] net/dpaa2: add mtu config support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 26/33] net/dpaa2: rx packet parsing and packet type support Hemant Agrawal
` (10 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 53 +++++++
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, 321 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 2a8d9e5..c26360d3 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
@@ -122,6 +128,53 @@ struct dpaa2_queue {
/*! Global MCP list */
extern void *(*rte_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
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 0e59203..d52fa39 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 7e64e60..c2015f0 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -681,6 +681,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -734,6 +736,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 26/33] net/dpaa2: rx packet parsing and packet type support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (24 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 25/33] net/dpaa2: add packet rx and tx support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 27/33] net/dpaa2: link status update Hemant Agrawal
` (9 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 c2015f0..521a066 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 27/33] net/dpaa2: link status update
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (25 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 26/33] net/dpaa2: rx packet parsing and packet type support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 28/33] net/dpaa2: basic stats support Hemant Agrawal
` (8 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 521a066..4e08096 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 28/33] net/dpaa2: basic stats support
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (26 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 27/33] net/dpaa2: link status update Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 29/33] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (7 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 4e08096..eed0136 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 29/33] net/dpaa2: enable stashing for LS2088A devices
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (27 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 28/33] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-01-23 11:59 ` Hemant Agrawal
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 30/33] net/dpaa2: add support for non hw buffer pool packet transmit Hemant Agrawal
` (6 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 11:59 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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 eed0136..6609a9b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 30/33] net/dpaa2: add support for non hw buffer pool packet transmit
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (28 preceding siblings ...)
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 29/33] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-01-23 12:00 ` Hemant Agrawal
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 31/33] net/dpaa2: enabling the use of physical addresses Hemant Agrawal
` (5 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 12:00 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..a94761c 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_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),
+ rte_dpaa2_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 +380,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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 31/33] net/dpaa2: enabling the use of physical addresses
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (29 preceding siblings ...)
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 30/33] net/dpaa2: add support for non hw buffer pool packet transmit Hemant Agrawal
@ 2017-01-23 12:00 ` Hemant Agrawal
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 32/33] bus/fslmc: add support for dmamap to ARM SMMU Hemant Agrawal
` (4 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 12:00 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_pvt.h | 66 +++++++++++++++++++++++++++++++
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, 95 insertions(+), 12 deletions(-)
diff --git a/config/common_base b/config/common_base
index dd3de11..6f1787a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -291,6 +291,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
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 3cdb31b..29a56c7 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
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/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index c26360d3..ad8a22f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -175,6 +175,72 @@ 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 */
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
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 a94761c..49b4558 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_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 0c8de51..ca42418 100644
--- a/drivers/pool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -203,9 +203,14 @@ void rte_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);
@@ -214,8 +219,15 @@ void rte_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,
@@ -288,6 +300,7 @@ int rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 32/33] bus/fslmc: add support for dmamap to ARM SMMU
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (30 preceding siblings ...)
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 31/33] net/dpaa2: enabling the use of physical addresses Hemant Agrawal
@ 2017-01-23 12:00 ` Hemant Agrawal
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 33/33] drivers/common/dpaa2: frame queue based dq storage alloc Hemant Agrawal
` (3 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 12:00 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 96 +++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 1 +
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 2 +
4 files changed, 100 insertions(+)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index fc017fc..5f1d1b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -76,8 +76,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 *(*rte_mcp_ptr_list);
static uint32_t mcp_id;
+static int is_dma_done;
static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
{
@@ -147,6 +149,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,71 @@ int vfio_dmamap_mem_region(uint64_t vaddr,
return 0;
}
+int rte_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 80c6869..53dd0b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -70,6 +70,7 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(void);
+int rte_fslmc_vfio_dmamap(void);
/* create dpio device */
int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4a8f478..505873a 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -52,6 +52,7 @@ DPDK_17.02 {
per_lcore__dpaa2_io;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_fslmc_vfio_dmamap;
rte_mcp_ptr_list;
local: *;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 6609a9b..cbfbc7a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -910,6 +910,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv6 33/33] drivers/common/dpaa2: frame queue based dq storage alloc
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (31 preceding siblings ...)
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 32/33] bus/fslmc: add support for dmamap to ARM SMMU Hemant Agrawal
@ 2017-01-23 12:00 ` Hemant Agrawal
2017-01-23 17:56 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Ferruh Yigit
` (2 subsequent siblings)
35 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-23 12:00 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob, Hemant Agrawal
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/bus/fslmc/portal/dpaa2_hw_dpio.c | 32 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 7 +++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
4 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index bd1f643..c80d6c5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index b1a1b8f..f2e1168 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -59,5 +59,12 @@ struct dpaa2_io_portal_t {
/* Affine additional DPIO portal to current crypto processing thread */
int dpaa2_affine_qbman_swp_sec(void);
+/* 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/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 505873a..4298d77 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -4,7 +4,9 @@ DPDK_17.02 {
dpaa2_affine_qbman_swp;
dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
+ dpaa2_alloc_dq_storage;
dpaa2_free_dpbp_dev;
+ dpaa2_free_dq_storage;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index cbfbc7a..67eb34d 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (32 preceding siblings ...)
2017-01-23 12:00 ` [dpdk-dev] [PATCHv6 33/33] drivers/common/dpaa2: frame queue based dq storage alloc Hemant Agrawal
@ 2017-01-23 17:56 ` Ferruh Yigit
2017-01-26 11:55 ` Ferruh Yigit
2017-01-23 17:58 ` Ferruh Yigit
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
35 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:56 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
<...>
>
> Hemant Agrawal (33):
> mk/dpaa2: add the crc support to the machine type
> drivers/common/dpaa2: adding qbman driver
> bus/fslmc: introducing fsl-mc bus driver
> bus/fslmc: introduce mc object functions
> bus/fslmc: add mc dpni object support
> bus/fslmc: add mc dpio object support
> bus/fslmc: add mc dpbp object support
> bus/fslmc: add mc dpseci object support
> eal/vfio: adding vfio utility functions in map file
> bus/fslmc: add vfio support
> bus/fslmc: scan for net and sec devices
> net/dpaa2: introducing NXP dpaa2 pmd driver
> doc: add dpaa2 nic details
> bus/fslmc: add debug log message support
> drivers/common/dpaa2: dpio portal driver
> drivers/pool/dpaa2: adding hw offloaded mempool
> drivers/common/dpaa2: dpio routine to affine to crypto threads
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add rss flow distribution
> net/dpaa2: configure mac address at init
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for l3 and l4 checksum offload
> net/dpaa2: add support for promiscuous mode
> net/dpaa2: add mtu config support
> net/dpaa2: add packet rx and tx support
> net/dpaa2: rx packet parsing and packet type support
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: add support for non hw buffer pool packet transmit
> net/dpaa2: enabling the use of physical addresses
> bus/fslmc: add support for dmamap to ARM SMMU
> drivers/common/dpaa2: frame queue based dq storage alloc
>
<...>
> 66 files changed, 15984 insertions(+), 5 deletions(-)
I have some concerns about this PMD,
- This is a big one, as seen above, and it is hard to review it all, I
don't feel confident about the amount of review done, more reviewers are
welcome. And we are already post RC1.
- Although this driver introduces a new bus type, in some parts, driver
still has virtual devices like usage, perhaps this is not because of
this PMD but mostly because of overall dpdk bus structure. Still I have
concerns about getting driver like this, and would like to hear more
comments.
Thanks,
ferruh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-23 17:56 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Ferruh Yigit
@ 2017-01-26 11:55 ` Ferruh Yigit
2017-01-26 12:18 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-26 11:55 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 5:56 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> <...>
>
>>
>> Hemant Agrawal (33):
>> mk/dpaa2: add the crc support to the machine type
>> drivers/common/dpaa2: adding qbman driver
>> bus/fslmc: introducing fsl-mc bus driver
>> bus/fslmc: introduce mc object functions
>> bus/fslmc: add mc dpni object support
>> bus/fslmc: add mc dpio object support
>> bus/fslmc: add mc dpbp object support
>> bus/fslmc: add mc dpseci object support
>> eal/vfio: adding vfio utility functions in map file
>> bus/fslmc: add vfio support
>> bus/fslmc: scan for net and sec devices
>> net/dpaa2: introducing NXP dpaa2 pmd driver
>> doc: add dpaa2 nic details
>> bus/fslmc: add debug log message support
>> drivers/common/dpaa2: dpio portal driver
>> drivers/pool/dpaa2: adding hw offloaded mempool
>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>> net/dpaa2: adding eth ops to dpaa2
>> net/dpaa2: add rss flow distribution
>> net/dpaa2: configure mac address at init
>> net/dpaa2: attach the buffer pool to dpni
>> net/dpaa2: add support for l3 and l4 checksum offload
>> net/dpaa2: add support for promiscuous mode
>> net/dpaa2: add mtu config support
>> net/dpaa2: add packet rx and tx support
>> net/dpaa2: rx packet parsing and packet type support
>> net/dpaa2: link status update
>> net/dpaa2: basic stats support
>> net/dpaa2: enable stashing for LS2088A devices
>> net/dpaa2: add support for non hw buffer pool packet transmit
>> net/dpaa2: enabling the use of physical addresses
>> bus/fslmc: add support for dmamap to ARM SMMU
>> drivers/common/dpaa2: frame queue based dq storage alloc
>>
> <...>
>> 66 files changed, 15984 insertions(+), 5 deletions(-)
>
> I have some concerns about this PMD,
>
> - This is a big one, as seen above, and it is hard to review it all, I
> don't feel confident about the amount of review done, more reviewers are
> welcome. And we are already post RC1.
>
> - Although this driver introduces a new bus type, in some parts, driver
> still has virtual devices like usage, perhaps this is not because of
> this PMD but mostly because of overall dpdk bus structure. Still I have
> concerns about getting driver like this, and would like to hear more
> comments.
As a result of above concerns, I propose postponing this PMD to 17.05
release.
The dependent rte_bus just get into main repo less than two weeks ago,
also this driver comes with a few new things first of its kind, and it
matters to make first samples correct.
I believe it is good to let the PMD be around a little more to give
chance to both PMD and rte_bus to become more mature.
Thanks,
ferruh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-26 11:55 ` Ferruh Yigit
@ 2017-01-26 12:18 ` Hemant Agrawal
2017-01-26 18:02 ` Thomas Monjalon
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-26 12:18 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/26/2017 5:25 PM, Ferruh Yigit wrote:
> On 1/23/2017 5:56 PM, Ferruh Yigit wrote:
>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> <...>
>>
>>>
>>> Hemant Agrawal (33):
>>> mk/dpaa2: add the crc support to the machine type
>>> drivers/common/dpaa2: adding qbman driver
>>> bus/fslmc: introducing fsl-mc bus driver
>>> bus/fslmc: introduce mc object functions
>>> bus/fslmc: add mc dpni object support
>>> bus/fslmc: add mc dpio object support
>>> bus/fslmc: add mc dpbp object support
>>> bus/fslmc: add mc dpseci object support
>>> eal/vfio: adding vfio utility functions in map file
>>> bus/fslmc: add vfio support
>>> bus/fslmc: scan for net and sec devices
>>> net/dpaa2: introducing NXP dpaa2 pmd driver
>>> doc: add dpaa2 nic details
>>> bus/fslmc: add debug log message support
>>> drivers/common/dpaa2: dpio portal driver
>>> drivers/pool/dpaa2: adding hw offloaded mempool
>>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>>> net/dpaa2: adding eth ops to dpaa2
>>> net/dpaa2: add rss flow distribution
>>> net/dpaa2: configure mac address at init
>>> net/dpaa2: attach the buffer pool to dpni
>>> net/dpaa2: add support for l3 and l4 checksum offload
>>> net/dpaa2: add support for promiscuous mode
>>> net/dpaa2: add mtu config support
>>> net/dpaa2: add packet rx and tx support
>>> net/dpaa2: rx packet parsing and packet type support
>>> net/dpaa2: link status update
>>> net/dpaa2: basic stats support
>>> net/dpaa2: enable stashing for LS2088A devices
>>> net/dpaa2: add support for non hw buffer pool packet transmit
>>> net/dpaa2: enabling the use of physical addresses
>>> bus/fslmc: add support for dmamap to ARM SMMU
>>> drivers/common/dpaa2: frame queue based dq storage alloc
>>>
>> <...>
>>> 66 files changed, 15984 insertions(+), 5 deletions(-)
>>
>> I have some concerns about this PMD,
>>
>> - This is a big one, as seen above, and it is hard to review it all, I
>> don't feel confident about the amount of review done, more reviewers are
>> welcome. And we are already post RC1.
>>
>> - Although this driver introduces a new bus type, in some parts, driver
>> still has virtual devices like usage, perhaps this is not because of
>> this PMD but mostly because of overall dpdk bus structure. Still I have
>> concerns about getting driver like this, and would like to hear more
>> comments.
>
> As a result of above concerns, I propose postponing this PMD to 17.05
> release.
>
> The dependent rte_bus just get into main repo less than two weeks ago,
> also this driver comes with a few new things first of its kind, and it
> matters to make first samples correct.
>
> I believe it is good to let the PMD be around a little more to give
> chance to both PMD and rte_bus to become more mature.
>
I agree that this driver is coming with few new thing and it is taking
time to come up with agreeable and good solution for some of this new stuff.
Finalizing the right framework for adding SoC based drivers took a
little longer than expected. But thanks to Thomas help in the last that
we got the basic bus framework integrated.
Thomos- is it possible to integrate it early in 17.05 cycle, rather than
waiting till end?
> Thanks,
> ferruh
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-26 12:18 ` Hemant Agrawal
@ 2017-01-26 18:02 ` Thomas Monjalon
0 siblings, 0 replies; 549+ messages in thread
From: Thomas Monjalon @ 2017-01-26 18:02 UTC (permalink / raw)
To: Hemant Agrawal, Ferruh Yigit
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara, jerin.jacob
2017-01-26 17:48, Hemant Agrawal:
> On 1/26/2017 5:25 PM, Ferruh Yigit wrote:
> > On 1/23/2017 5:56 PM, Ferruh Yigit wrote:
> >> I have some concerns about this PMD,
> >>
> >> - This is a big one, as seen above, and it is hard to review it all, I
> >> don't feel confident about the amount of review done, more reviewers are
> >> welcome. And we are already post RC1.
> >>
> >> - Although this driver introduces a new bus type, in some parts, driver
> >> still has virtual devices like usage, perhaps this is not because of
> >> this PMD but mostly because of overall dpdk bus structure. Still I have
> >> concerns about getting driver like this, and would like to hear more
> >> comments.
> >
> > As a result of above concerns, I propose postponing this PMD to 17.05
> > release.
> >
> > The dependent rte_bus just get into main repo less than two weeks ago,
> > also this driver comes with a few new things first of its kind, and it
> > matters to make first samples correct.
> >
> > I believe it is good to let the PMD be around a little more to give
> > chance to both PMD and rte_bus to become more mature.
> >
>
> I agree that this driver is coming with few new thing and it is taking
> time to come up with agreeable and good solution for some of this new stuff.
>
> Finalizing the right framework for adding SoC based drivers took a
> little longer than expected. But thanks to Thomas help in the last that
> we got the basic bus framework integrated.
>
> Thomos- is it possible to integrate it early in 17.05 cycle, rather than
> waiting till end?
Yes that's a really good question.
I could reword it to "when do we pull from next-* trees"?
I think you and Ferruh can work to integrate it in next-net before the
beginning of 17.05. So I could do a first pull of next-net when starting
the 17.05 cycle.
Note that 17.05 will start in few weeks.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (33 preceding siblings ...)
2017-01-23 17:56 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Ferruh Yigit
@ 2017-01-23 17:58 ` Ferruh Yigit
2017-01-24 11:25 ` Ferruh Yigit
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
35 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-23 17:58 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
<...>
>
> Hemant Agrawal (33):
> mk/dpaa2: add the crc support to the machine type
> drivers/common/dpaa2: adding qbman driver
> bus/fslmc: introducing fsl-mc bus driver
> bus/fslmc: introduce mc object functions
> bus/fslmc: add mc dpni object support
> bus/fslmc: add mc dpio object support
> bus/fslmc: add mc dpbp object support
> bus/fslmc: add mc dpseci object support
> eal/vfio: adding vfio utility functions in map file
> bus/fslmc: add vfio support
> bus/fslmc: scan for net and sec devices
> net/dpaa2: introducing NXP dpaa2 pmd driver
> doc: add dpaa2 nic details
> bus/fslmc: add debug log message support
> drivers/common/dpaa2: dpio portal driver
> drivers/pool/dpaa2: adding hw offloaded mempool
> drivers/common/dpaa2: dpio routine to affine to crypto threads
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add rss flow distribution
> net/dpaa2: configure mac address at init
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for l3 and l4 checksum offload
> net/dpaa2: add support for promiscuous mode
> net/dpaa2: add mtu config support
> net/dpaa2: add packet rx and tx support
> net/dpaa2: rx packet parsing and packet type support
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: add support for non hw buffer pool packet transmit
> net/dpaa2: enabling the use of physical addresses
> bus/fslmc: add support for dmamap to ARM SMMU
> drivers/common/dpaa2: frame queue based dq storage alloc
>
devtools/check-git-log.sh gives following errors:
Wrong headline prefix:
bus/fslmc: add debug log message support
drivers/common/dpaa2: dpio portal driver
drivers/common/dpaa2: dpio routine to affine to crypto threads
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for l3 and l4 checksum offload
net/dpaa2: add mtu config support
net/dpaa2: add packet rx and tx support
net/dpaa2: enabling the use of physical addresses
bus/fslmc: add support for dmamap to ARM SMMU
drivers/common/dpaa2: frame queue based dq storage alloc
Wrong headline lowercase:
net/dpaa2: introducing NXP dpaa2 pmd driver
doc: add dpaa2 nic details
drivers/pool/dpaa2: adding hw offloaded mempool
net/dpaa2: add rss flow distribution
net/dpaa2: configure mac address at init
net/dpaa2: add support for l3 and l4 checksum offload
net/dpaa2: add mtu config support
net/dpaa2: add packet rx and tx support
net/dpaa2: rx packet parsing and packet type support
net/dpaa2: add support for non hw buffer pool packet transmit
Headline too long:
drivers/common/dpaa2: dpio routine to affine to crypto threads
net/dpaa2: add support for non hw buffer pool packet transmit
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-23 17:58 ` Ferruh Yigit
@ 2017-01-24 11:25 ` Ferruh Yigit
2017-01-25 4:03 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-01-24 11:25 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/23/2017 5:58 PM, Ferruh Yigit wrote:
> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
> <...>
>
>>
>> Hemant Agrawal (33):
>> mk/dpaa2: add the crc support to the machine type
>> drivers/common/dpaa2: adding qbman driver
>> bus/fslmc: introducing fsl-mc bus driver
>> bus/fslmc: introduce mc object functions
>> bus/fslmc: add mc dpni object support
>> bus/fslmc: add mc dpio object support
>> bus/fslmc: add mc dpbp object support
>> bus/fslmc: add mc dpseci object support
>> eal/vfio: adding vfio utility functions in map file
>> bus/fslmc: add vfio support
>> bus/fslmc: scan for net and sec devices
>> net/dpaa2: introducing NXP dpaa2 pmd driver
>> doc: add dpaa2 nic details
>> bus/fslmc: add debug log message support
>> drivers/common/dpaa2: dpio portal driver
>> drivers/pool/dpaa2: adding hw offloaded mempool
>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>> net/dpaa2: adding eth ops to dpaa2
>> net/dpaa2: add rss flow distribution
>> net/dpaa2: configure mac address at init
>> net/dpaa2: attach the buffer pool to dpni
>> net/dpaa2: add support for l3 and l4 checksum offload
>> net/dpaa2: add support for promiscuous mode
>> net/dpaa2: add mtu config support
>> net/dpaa2: add packet rx and tx support
>> net/dpaa2: rx packet parsing and packet type support
>> net/dpaa2: link status update
>> net/dpaa2: basic stats support
>> net/dpaa2: enable stashing for LS2088A devices
>> net/dpaa2: add support for non hw buffer pool packet transmit
>> net/dpaa2: enabling the use of physical addresses
>> bus/fslmc: add support for dmamap to ARM SMMU
>> drivers/common/dpaa2: frame queue based dq storage alloc
>>
>
> devtools/check-git-log.sh gives following errors:
>
> Wrong headline prefix:
> bus/fslmc: add debug log message support
Some of these warnings are because of the assumption that the scope of
changed files are limited to the patch title tag.
For example, for this patch, because of the "bus/fslmc:", it is expected
that all modified files are under "drivers/bus/fslmc" folder, but this
patch modifies:
bus/fslmc/*
common/dpaa2/*
net/dpaa2/*
I can guess different dpaa2 modules (bus/common/net) has dependencies to
each other, and may not always be possible to separate them. This needs
to be investigated per patch.
But the more they are separated, easier to review / understand them. And
I am aware this is easier to say than to do it.
thanks,
ferruh
> drivers/common/dpaa2: dpio portal driver
Or this one, scope is "drivers/common/dpaa2", but all the modifies files
are under "/drivers/bus/*".
> drivers/common/dpaa2: dpio routine to affine to crypto threads
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for l3 and l4 checksum offload
> net/dpaa2: add mtu config support
> net/dpaa2: add packet rx and tx support
> net/dpaa2: enabling the use of physical addresses
> bus/fslmc: add support for dmamap to ARM SMMU
> drivers/common/dpaa2: frame queue based dq storage alloc
> Wrong headline lowercase:
> net/dpaa2: introducing NXP dpaa2 pmd driver
> doc: add dpaa2 nic details
> drivers/pool/dpaa2: adding hw offloaded mempool
> net/dpaa2: add rss flow distribution
> net/dpaa2: configure mac address at init
> net/dpaa2: add support for l3 and l4 checksum offload
> net/dpaa2: add mtu config support
> net/dpaa2: add packet rx and tx support
> net/dpaa2: rx packet parsing and packet type support
> net/dpaa2: add support for non hw buffer pool packet transmit
> Headline too long:
> drivers/common/dpaa2: dpio routine to affine to crypto threads
> net/dpaa2: add support for non hw buffer pool packet transmit
>
> <...>
>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD
2017-01-24 11:25 ` Ferruh Yigit
@ 2017-01-25 4:03 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-01-25 4:03 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 1/24/2017 4:55 PM, Ferruh Yigit wrote:
> On 1/23/2017 5:58 PM, Ferruh Yigit wrote:
>> On 1/23/2017 11:59 AM, Hemant Agrawal wrote:
>> <...>
>>
>>>
>>> Hemant Agrawal (33):
>>> mk/dpaa2: add the crc support to the machine type
>>> drivers/common/dpaa2: adding qbman driver
>>> bus/fslmc: introducing fsl-mc bus driver
>>> bus/fslmc: introduce mc object functions
>>> bus/fslmc: add mc dpni object support
>>> bus/fslmc: add mc dpio object support
>>> bus/fslmc: add mc dpbp object support
>>> bus/fslmc: add mc dpseci object support
>>> eal/vfio: adding vfio utility functions in map file
>>> bus/fslmc: add vfio support
>>> bus/fslmc: scan for net and sec devices
>>> net/dpaa2: introducing NXP dpaa2 pmd driver
>>> doc: add dpaa2 nic details
>>> bus/fslmc: add debug log message support
>>> drivers/common/dpaa2: dpio portal driver
>>> drivers/pool/dpaa2: adding hw offloaded mempool
>>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>>> net/dpaa2: adding eth ops to dpaa2
>>> net/dpaa2: add rss flow distribution
>>> net/dpaa2: configure mac address at init
>>> net/dpaa2: attach the buffer pool to dpni
>>> net/dpaa2: add support for l3 and l4 checksum offload
>>> net/dpaa2: add support for promiscuous mode
>>> net/dpaa2: add mtu config support
>>> net/dpaa2: add packet rx and tx support
>>> net/dpaa2: rx packet parsing and packet type support
>>> net/dpaa2: link status update
>>> net/dpaa2: basic stats support
>>> net/dpaa2: enable stashing for LS2088A devices
>>> net/dpaa2: add support for non hw buffer pool packet transmit
>>> net/dpaa2: enabling the use of physical addresses
>>> bus/fslmc: add support for dmamap to ARM SMMU
>>> drivers/common/dpaa2: frame queue based dq storage alloc
>>>
>>
>> devtools/check-git-log.sh gives following errors:
>>
>> Wrong headline prefix:
>> bus/fslmc: add debug log message support
>
> Some of these warnings are because of the assumption that the scope of
> changed files are limited to the patch title tag.
>
> For example, for this patch, because of the "bus/fslmc:", it is expected
> that all modified files are under "drivers/bus/fslmc" folder, but this
> patch modifies:
> bus/fslmc/*
> common/dpaa2/*
> net/dpaa2/*
>
> I can guess different dpaa2 modules (bus/common/net) has dependencies to
> each other, and may not always be possible to separate them. This needs
> to be investigated per patch.
>
> But the more they are separated, easier to review / understand them. And
> I am aware this is easier to say than to do it.
>
Thanks for your comments.
I will make an attempt to fix them.
> thanks,
> ferruh
>
>
>> drivers/common/dpaa2: dpio portal driver
>
> Or this one, scope is "drivers/common/dpaa2", but all the modifies files
> are under "/drivers/bus/*".
>
>
>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>> net/dpaa2: adding eth ops to dpaa2
>> net/dpaa2: attach the buffer pool to dpni
>> net/dpaa2: add support for l3 and l4 checksum offload
>> net/dpaa2: add mtu config support
>> net/dpaa2: add packet rx and tx support
>> net/dpaa2: enabling the use of physical addresses
>> bus/fslmc: add support for dmamap to ARM SMMU
>> drivers/common/dpaa2: frame queue based dq storage alloc
>> Wrong headline lowercase:
>> net/dpaa2: introducing NXP dpaa2 pmd driver
>> doc: add dpaa2 nic details
>> drivers/pool/dpaa2: adding hw offloaded mempool
>> net/dpaa2: add rss flow distribution
>> net/dpaa2: configure mac address at init
>> net/dpaa2: add support for l3 and l4 checksum offload
>> net/dpaa2: add mtu config support
>> net/dpaa2: add packet rx and tx support
>> net/dpaa2: rx packet parsing and packet type support
>> net/dpaa2: add support for non hw buffer pool packet transmit
>> Headline too long:
>> drivers/common/dpaa2: dpio routine to affine to crypto threads
>> net/dpaa2: add support for non hw buffer pool packet transmit
>>
>> <...>
>>
>>
>>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-01-23 11:59 ` [dpdk-dev] [PATCHv6 00/33] NXP DPAA2 PMD Hemant Agrawal
` (34 preceding siblings ...)
2017-01-23 17:58 ` Ferruh Yigit
@ 2017-02-16 0:38 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 01/47] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
` (48 more replies)
35 siblings, 49 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:38 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
fsl-mc bus driver and network SoC PMD. This version of the driver
supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
A brief description of architecture is given below; detailed description
is part of the documentation in the patches itself.
DPAA2 contains hardware component called the Management Complex (or MC).
It manages the DPAA2 hardware resources. The MC provides an object-based
abstraction for software drivers to use the DPAA2 hardware.
Some of the key objects are:
- DPNI, which refers to the network interface object.
- DPBP, which refers to HW based memory pool object
- DPIO, refers to processing context for accessing QBMAN
Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
software/user-space to the queues and buffers implemented in the hardware.
The patch series could be logically structured into following sub-areas:
1. Make file changes for crc in armv8 core machine type and driver dependency
2. Common dpaa2 hw accelerator drivers for QBMAN.
3. Indroducing fsl-mc bus as rte_bus, it's componenets.
4. Introducing dpaa2 pmd driver
5. Introducing dpaa2 mempool
6. Support for DPAA2 Ethernet Device (ethdev)
7. Additional functionality in DPAA2 ethdev.
The following design decisions are made during development:
1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
These drivers will be shared with dpaa2 based crypto drivers.
2. DPAA2 implements the HW mempool offload with DPBP object.
- The new pool is being configured using compile time option and pool name
as "dpaa2".
3. It maintains per lcore DPIO objects and affine the DPIO instance to the
processing threads accessing the QBMAN HW.
Prerequisites:
- For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
- At present the series has limited support for Ethernet functions. But,
more functionality would be made available in a phased manner.
Future Changes/Caveats:
1. VFIO code for fsl-mc bus is different than eal-vfio code for pci bus.
This need to be re-worked to make possible re-use of the existing code.
2. DPAA2 PMD has dependency on internal driver component and bus. The internal
driver apis are not having "rte_" naming convention.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
---
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (46):
mk/dpaa2: add the crc support to the machine type
common/dpaa2: adding qbman driver
bus/fslmc: introducing fsl-mc bus driver
bus/fslmc: introduce MC object functions
bus/fslmc: add mc dpni object support
bus/fslmc: add mc dpio object support
bus/fslmc: add mc dpbp object support
bus/fslmc: add mc dpseci object support
eal/vfio: adding vfio utility functions in map file
bus/fslmc: add vfio support
bus/fslmc: scan for net and sec devices
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
bus/fslmc: add debug log support
net/dpaa2: add debug log support
common/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
bus/fslmc: dpio portal driver
pool/dpaa2: add DPAA2 hardware offloaded mempool
bus/fslmc: affine dpio to crypto threads
bus/fslmc: define queues for DPAA2 devices
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
bus/fslmc: define hardware annotation area size
net/dpaa2: attach the buffer pool to dpni
bus/fslmc: introduce true and false macros
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
bus/fslmc: define VLAN header length
net/dpaa2: add MTU configuration support
bus/fslmc: add packet FLE definitions
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
bus/fslmc: add physical-virtual address translation helpers
pool/dpaa2: enable physical addressing for pool buffers
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
bus/fslmc: add support for DMA mapping for ARM SMMU
net/dpaa2: enable DMA Mapping during device scanning
bus/fslmc: frame queue based dq storage alloc
net/dpaa2: enable frame queue based dequeuing
Shreyansh Jain (1):
mk: handle intra drivers dependencies for shared build
MAINTAINERS | 8 +
config/common_base | 21 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 27 +-
doc/guides/nics/dpaa2.rst | 593 ++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
drivers/Makefile | 3 +
drivers/bus/Makefile | 38 +
drivers/bus/fslmc/Makefile | 81 ++
drivers/bus/fslmc/fslmc_bus.c | 135 ++
drivers/bus/fslmc/fslmc_logs.h | 76 +
drivers/bus/fslmc/fslmc_vfio.c | 629 ++++++++
drivers/bus/fslmc/fslmc_vfio.h | 82 ++
drivers/bus/fslmc/mc/dpbp.c | 237 ++++
drivers/bus/fslmc/mc/dpio.c | 279 ++++
drivers/bus/fslmc/mc/dpni.c | 739 ++++++++++
drivers/bus/fslmc/mc/dpseci.c | 534 +++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 +++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++
drivers/bus/fslmc/mc/fsl_dpkg.h | 184 +++
drivers/bus/fslmc/mc/fsl_dpni.h | 1217 ++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 334 +++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 668 +++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 255 ++++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 ++
drivers/bus/fslmc/mc/fsl_net.h | 487 +++++++
drivers/bus/fslmc/mc/mc_sys.c | 114 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 441 ++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 70 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 247 ++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 61 +
drivers/bus/fslmc/rte_fslmc.h | 148 ++
drivers/common/Makefile | 48 +
drivers/common/dpaa2/Makefile | 48 +
drivers/common/dpaa2/qbman/Makefile | 70 +
drivers/common/dpaa2/qbman/include/compat.h | 406 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 160 +++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1496 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 277 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 170 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 385 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 73 +
.../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 27 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 76 +
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 +++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1040 ++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 ++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
drivers/pool/Makefile | 40 +
drivers/pool/dpaa2/Makefile | 74 +
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 352 +++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
mk/machine/dpaa2/rte.vars.mk | 5 +-
mk/rte.app.mk | 4 +
mk/rte.lib.mk | 2 +-
67 files changed, 15993 insertions(+), 6 deletions(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
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_pool_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 01/47] mk/dpaa2: add the crc support to the machine type
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 02/47] mk: handle intra drivers dependencies for shared build Hemant Agrawal
` (47 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
mk/machine/dpaa2/rte.vars.mk | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mk/machine/dpaa2/rte.vars.mk b/mk/machine/dpaa2/rte.vars.mk
index 8541633..e4735c2 100644
--- a/mk/machine/dpaa2/rte.vars.mk
+++ b/mk/machine/dpaa2/rte.vars.mk
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -53,7 +54,7 @@
# CPU_CFLAGS =
# CPU_LDFLAGS =
# CPU_ASFLAGS =
-MACHINE_CFLAGS += -march=armv8-a
+MACHINE_CFLAGS += -march=armv8-a+crc
ifdef CONFIG_RTE_ARCH_ARM_TUNE
MACHINE_CFLAGS += -mcpu=$(CONFIG_RTE_ARCH_ARM_TUNE)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 02/47] mk: handle intra drivers dependencies for shared build
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 01/47] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Hemant Agrawal
` (46 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
From: Shreyansh Jain <shreyansh.jain@nxp.com>
Suggested-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
mk/rte.lib.mk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 33a5f5a..ac4df9a 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -79,7 +79,7 @@ endif
# Translate DEPDIRS-y into LDLIBS
# Ignore (sub)directory dependencies which do not provide an actual library
-_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
+_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat drivers/%
_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
_LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 01/47] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 02/47] mk: handle intra drivers dependencies for shared build Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 5:57 ` Shreyansh Jain
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 04/47] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
` (45 subsequent siblings)
48 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
QBMAN, is a hardware block which interfaces with the other
accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
SoC for queue, buffer and packet scheduling.
This patch introduces a userspace driver for interfacing with
the QBMAN hw block.
The qbman-portal component provides APIs to do the low level
hardware bit twiddling for operations such as:
-initializing Qman software portals
-building and sending portal commands
-portal interrupt configuration and processing
This same/similar code is used in kernel and compat file is used
to make it working in user space.
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 4 +
drivers/Makefile | 1 +
drivers/common/Makefile | 36 +
drivers/common/dpaa2/Makefile | 36 +
drivers/common/dpaa2/qbman/Makefile | 53 +
drivers/common/dpaa2/qbman/include/compat.h | 406 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 160 +++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1496 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 277 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 170 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 385 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 73 +
.../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 27 +
14 files changed, 4217 insertions(+)
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index cc3bf98..7ec5683 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -356,6 +356,10 @@ M: Alejandro Lucero <alejandro.lucero@netronome.com>
F: drivers/net/nfp/
F: doc/guides/nics/nfp.rst
+NXP dpaa2
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/common/dpaa2/
+
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/drivers/Makefile b/drivers/Makefile
index 81c03a8..d5580f6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -31,6 +31,7 @@
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..e5bfecb
--- /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_COMMON) += dpaa2
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
new file mode 100644
index 0000000..4960ebe
--- /dev/null
+++ b/drivers/common/dpaa2/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_COMMON) += qbman
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
new file mode 100644
index 0000000..5e64d23
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -0,0 +1,53 @@
+# 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_common_dpaa2_qbman.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+
+EXPORT_MAP := rte_common_dpaa2_qbman_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += \
+ qbman_portal.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/common/dpaa2/qbman/include/compat.h b/drivers/common/dpaa2/qbman/include/compat.h
new file mode 100644
index 0000000..28d7952
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/compat.h
@@ -0,0 +1,406 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 HEADER_COMPAT_H
+#define HEADER_COMPAT_H
+
+#include <sched.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <net/ethernet.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <assert.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <error.h>
+#include <rte_atomic.h>
+
+/* The following definitions are primarily to allow the single-source driver
+ * interfaces to be included by arbitrary program code. Ie. for interfaces that
+ * are also available in kernel-space, these definitions provide compatibility
+ * with certain attributes and types used in those interfaces.
+ */
+
+/* Required compiler attributes */
+#define __user
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+#undef container_of
+#define container_of(ptr, type, member) ({ \
+ typeof(((type *)0)->member)(*__mptr) = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#ifdef ARRAY_SIZE
+#undef ARRAY_SIZE
+#endif
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/* Required types */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uint64_t dma_addr_t;
+typedef cpu_set_t cpumask_t;
+typedef u32 compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+/* I/O operations */
+static inline u32 in_be32(volatile void *__p)
+{
+ volatile u32 *p = __p;
+ return *p;
+}
+
+static inline void out_be32(volatile void *__p, u32 val)
+{
+ volatile u32 *p = __p;
+ *p = val;
+}
+
+/* Debugging */
+#define prflush(fmt, args...) \
+ do { \
+ printf(fmt, ##args); \
+ fflush(stdout); \
+ } while (0)
+#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args)
+#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args)
+#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args)
+#define pr_info(fmt, args...) prflush(fmt, ##args)
+
+#ifdef pr_debug
+#undef pr_debug
+#endif
+#define pr_debug(fmt, args...) {}
+#define might_sleep_if(c) {}
+#define msleep(x) {}
+#define WARN_ON(c, str) \
+do { \
+ static int warned_##__LINE__; \
+ if ((c) && !warned_##__LINE__) { \
+ pr_warn("%s\n", str); \
+ pr_warn("(%s:%d)\n", __FILE__, __LINE__); \
+ warned_##__LINE__ = 1; \
+ } \
+} while (0)
+#define QBMAN_BUG_ON(c) WARN_ON(c, "BUG")
+
+#define ALIGN(x, a) (((x) + ((typeof(x))(a) - 1)) & ~((typeof(x))(a) - 1))
+
+/****************/
+/* Linked-lists */
+/****************/
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_HEAD(n) \
+struct list_head n = { \
+ .prev = &n, \
+ .next = &n \
+}
+
+#define INIT_LIST_HEAD(p) \
+do { \
+ struct list_head *__p298 = (p); \
+ __p298->next = __p298; \
+ __p298->prev = __p298->next; \
+} while (0)
+#define list_entry(node, type, member) \
+ (type *)((void *)node - offsetof(type, member))
+#define list_empty(p) \
+({ \
+ const struct list_head *__p298 = (p); \
+ ((__p298->next == __p298) && (__p298->prev == __p298)); \
+})
+#define list_add(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->next = __l298->next; \
+ __p298->prev = __l298; \
+ __l298->next->prev = __p298; \
+ __l298->next = __p298; \
+} while (0)
+#define list_add_tail(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->prev = __l298->prev; \
+ __p298->next = __l298; \
+ __l298->prev->next = __p298; \
+ __l298->prev = __p298; \
+} while (0)
+#define list_for_each(i, l) \
+ for (i = (l)->next; i != (l); i = i->next)
+#define list_for_each_safe(i, j, l) \
+ for (i = (l)->next, j = i->next; i != (l); \
+ i = j, j = i->next)
+#define list_for_each_entry(i, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \
+ i = list_entry(i->name.next, typeof(*i), name))
+#define list_for_each_entry_safe(i, j, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name), \
+ j = list_entry(i->name.next, typeof(*j), name); \
+ &i->name != (l); \
+ i = j, j = list_entry(j->name.next, typeof(*j), name))
+#define list_del(i) \
+do { \
+ (i)->next->prev = (i)->prev; \
+ (i)->prev->next = (i)->next; \
+} while (0)
+
+/* Other miscellaneous interfaces our APIs depend on; */
+
+#define lower_32_bits(x) ((u32)(x))
+#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16))
+
+/* Compiler/type stuff */
+typedef unsigned int gfp_t;
+typedef uint32_t phandle;
+
+#define __iomem
+#define EINTR 4
+#define ENODEV 19
+#define GFP_KERNEL 0
+#define __raw_readb(p) (*(const volatile unsigned char *)(p))
+#define __raw_readl(p) (*(const volatile unsigned int *)(p))
+#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); }
+
+/* memcpy() stuff - when you know alignments in advance */
+#ifdef CONFIG_TRY_BETTER_MEMCPY
+static inline void copy_words(void *dest, const void *src, size_t sz)
+{
+ u32 *__dest = dest;
+ const u32 *__src = src;
+ size_t __sz = sz >> 2;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x3);
+ QBMAN_BUG_ON((unsigned long)src & 0x3);
+ QBMAN_BUG_ON(sz & 0x3);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_shorts(void *dest, const void *src, size_t sz)
+{
+ u16 *__dest = dest;
+ const u16 *__src = src;
+ size_t __sz = sz >> 1;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x1);
+ QBMAN_BUG_ON((unsigned long)src & 0x1);
+ QBMAN_BUG_ON(sz & 0x1);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_bytes(void *dest, const void *src, size_t sz)
+{
+ u8 *__dest = dest;
+ const u8 *__src = src;
+
+ while (sz--)
+ *(__dest++) = *(__src++);
+}
+#else
+#define copy_words memcpy
+#define copy_shorts memcpy
+#define copy_bytes memcpy
+#endif
+
+/* Completion stuff */
+#define DECLARE_COMPLETION(n) int n = 0
+#define complete(n) { *n = 1; }
+#define wait_for_completion(n) \
+do { \
+ while (!*n) { \
+ bman_poll(); \
+ qman_poll(); \
+ } \
+ *n = 0; \
+} while (0)
+
+/* Allocator stuff */
+#define kmalloc(sz, t) malloc(sz)
+#define vmalloc(sz) malloc(sz)
+#define kfree(p) { if (p) free(p); }
+static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused)
+{
+ void *ptr = malloc(sz);
+
+ if (ptr)
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
+{
+ void *p;
+
+ if (posix_memalign(&p, 4096, 4096))
+ return 0;
+ memset(p, 0, 4096);
+ return (unsigned long)p;
+}
+
+static inline void free_page(unsigned long p)
+{
+ free((void *)p);
+}
+
+/* Bitfield stuff. */
+#define BITS_PER_ULONG (sizeof(unsigned long) << 3)
+#define SHIFT_PER_ULONG (((1 << 5) == BITS_PER_ULONG) ? 5 : 6)
+#define BITS_MASK(idx) ((unsigned long)1 << ((idx) & (BITS_PER_ULONG - 1)))
+#define BITS_IDX(idx) ((idx) >> SHIFT_PER_ULONG)
+static inline unsigned long test_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ return *p & mask;
+}
+
+static inline int test_bit(int idx, volatile unsigned long *bits)
+{
+ return test_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void set_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p |= mask;
+}
+
+static inline void set_bit(int idx, volatile unsigned long *bits)
+{
+ set_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p &= ~mask;
+}
+
+static inline void clear_bit(int idx, volatile unsigned long *bits)
+{
+ clear_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline unsigned long test_and_set_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ unsigned long ret = test_bits(mask, p);
+
+ set_bits(mask, p);
+ return ret;
+}
+
+static inline int test_and_set_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ set_bit(idx, bits);
+ return ret;
+}
+
+static inline int test_and_clear_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ clear_bit(idx, bits);
+ return ret;
+}
+
+static inline int find_next_zero_bit(unsigned long *bits, int limit, int idx)
+{
+ while ((++idx < limit) && test_bit(idx, bits))
+ ;
+ return idx;
+}
+
+static inline int find_first_zero_bit(unsigned long *bits, int limit)
+{
+ int idx = 0;
+
+ while (test_bit(idx, bits) && (++idx < limit))
+ ;
+ return idx;
+}
+
+static inline u64 div64_u64(u64 n, u64 d)
+{
+ return n / d;
+}
+
+#define atomic_t rte_atomic32_t
+#define atomic_read(v) rte_atomic32_read(v)
+#define atomic_set(v, i) rte_atomic32_set(v, i)
+
+#define atomic_inc(v) rte_atomic32_add(v, 1)
+#define atomic_dec(v) rte_atomic32_sub(v, 1)
+
+#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v)
+#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v)
+
+#define atomic_inc_return(v) rte_atomic32_add_return(v, 1)
+#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1)
+#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
+
+#endif /* HEADER_COMPAT_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
new file mode 100644
index 0000000..ee4b772
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
@@ -0,0 +1,160 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+typedef uint64_t dma_addr_t;
+
+/**
+ * DOC: QBMan basic structures
+ *
+ * The QBMan block descriptor, software portal descriptor and Frame descriptor
+ * are defined here.
+ *
+ */
+
+#define QMAN_REV_4000 0x04000000
+#define QMAN_REV_4100 0x04010000
+#define QMAN_REV_4101 0x04010001
+
+/**
+ * struct qbman_block_desc - qbman block descriptor structure
+ * @ccsr_reg_bar: CCSR register map.
+ * @irq_rerr: Recoverable error interrupt line.
+ * @irq_nrerr: Non-recoverable error interrupt line
+ *
+ * Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to.
+ */
+struct qbman_block_desc {
+ void *ccsr_reg_bar;
+ int irq_rerr;
+ int irq_nrerr;
+};
+
+enum qbman_eqcr_mode {
+ qman_eqcr_vb_ring = 2, /* Valid bit, with eqcr in ring mode */
+ qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */
+};
+
+/**
+ * struct qbman_swp_desc - qbman software portal descriptor structure
+ * @block: The QBMan instance.
+ * @cena_bar: Cache-enabled portal register map.
+ * @cinh_bar: Cache-inhibited portal register map.
+ * @irq: -1 if unused (or unassigned)
+ * @idx: SWPs within a QBMan are indexed. -1 if opaque to the user.
+ * @qman_version: the qman version.
+ * @eqcr_mode: Select the eqcr mode, currently only valid bit ring mode and
+ * valid bit array mode are supported.
+ *
+ * Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "MC bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering.
+ */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block;
+ uint8_t *cena_bar;
+ uint8_t *cinh_bar;
+ int irq;
+ int idx;
+ uint32_t qman_version;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/**
+ * struct qbman_fd - basci structure for qbman frame descriptor
+ * @words: for easier/faster copying the whole FD structure.
+ * @addr_lo: the lower 32 bits of the address in FD.
+ * @addr_hi: the upper 32 bits of the address in FD.
+ * @len: the length field in FD.
+ * @bpid_offset: represent the bpid and offset fields in FD. offset in
+ * the MS 16 bits, BPID in the LS 16 bits.
+ * @frc: frame context
+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
+ * @flc_lo: the lower 32bit of flow context.
+ * @flc_hi: the upper 32bits of flow context.
+ *
+ * Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ uint32_t bpid_offset;
+ uint32_t frc;
+ uint32_t ctrl;
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
new file mode 100644
index 0000000..7731772
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
@@ -0,0 +1,1093 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl_qbman_base.h>
+
+/**
+ * DOC - QBMan portal APIs to implement the following functions:
+ * - Initialize and destroy Software portal object.
+ * - Read and write Software portal interrupt registers.
+ * - Enqueue, including setting the enqueue descriptor, and issuing enqueue
+ * command etc.
+ * - Dequeue, including setting the dequeue descriptor, issuing dequeue command,
+ * parsing the dequeue response in DQRR and memeory, parsing the state change
+ * notifications etc.
+ * - Release, including setting the release descriptor, and issuing the buffer
+ * release command.
+ * - Acquire, acquire the buffer from the given buffer pool.
+ * - FQ management.
+ * - Channel management, enable/disable CDAN with or without context.
+ */
+
+/**
+ * qbman_swp_init() - Create a functional object representing the given
+ * QBMan portal descriptor.
+ * @d: the given qbman swp descriptor
+ *
+ * Return qbman_swp portal object for success, NULL if the object cannot
+ * be created.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
+
+/**
+ * qbman_swp_finish() - Create and destroy a functional object representing
+ * the given QBMan portal descriptor.
+ * @p: the qbman_swp object to be destroyed.
+ *
+ */
+void qbman_swp_finish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_get_desc() - Get the descriptor of the given portal object.
+ * @p: the given portal object.
+ *
+ * Return the descriptor for this portal.
+ */
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p);
+
+ /**************/
+ /* Interrupts */
+ /**************/
+
+/* EQCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_EQRI ((uint32_t)0x00000001)
+/* Enqueue command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_EQDI ((uint32_t)0x00000002)
+/* DQRR non-empty interrupt */
+#define QBMAN_SWP_INTERRUPT_DQRI ((uint32_t)0x00000004)
+/* RCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_RCRI ((uint32_t)0x00000008)
+/* Release command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_RCDI ((uint32_t)0x00000010)
+/* Volatile dequeue command interrupt */
+#define QBMAN_SWP_INTERRUPT_VDCI ((uint32_t)0x00000020)
+
+/**
+ * qbman_swp_interrupt_get_vanish() - Get the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISDR register.
+ */
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_vanish() - Set the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IDSR register.
+ */
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_read_status() - Get the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISR register.
+ */
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_clear_status() - Set the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_ISR register.
+ */
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_trigger() - Get the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IER register.
+ */
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_trigger() - Set the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IER register.
+ */
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_inhibit() - Get the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IIR register.
+ */
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_inhibit() - Set the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IIR register.
+ */
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/**
+ * struct qbman_result - structure for qbman dequeue response and/or
+ * notification.
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * possible qbman dequeue result.
+ */
+struct qbman_result {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* TODO:
+ *A DQRI interrupt can be generated when there are dequeue results on the
+ * portal's DQRR (this mechanism does not deal with "pull" dequeues to
+ * user-supplied 'storage' addresses). There are two parameters to this
+ * interrupt source, one is a threshold and the other is a timeout. The
+ * interrupt will fire if either the fill-level of the ring exceeds 'thresh', or
+ * if the ring has been non-empty for been longer than 'timeout' nanoseconds.
+ * For timeout, an approximation to the desired nanosecond-granularity value is
+ * made, so there are get and set APIs to allow the user to see what actual
+ * timeout is set (compared to the timeout that was requested).
+ */
+int qbman_swp_dequeue_thresh(struct qbman_swp *s, unsigned int thresh);
+int qbman_swp_dequeue_set_timeout(struct qbman_swp *s, unsigned int timeout);
+int qbman_swp_dequeue_get_timeout(struct qbman_swp *s, unsigned int *timeout);
+
+/* ------------------- */
+/* Push-mode dequeuing */
+/* ------------------- */
+
+/* The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+
+/**
+ * qbman_swp_push_get() - Get the push dequeue setup.
+ * @s: the software portal object.
+ * @channel_idx: the channel index to query.
+ * @enabled: returned boolean to show whether the push dequeue is enabled for
+ * the given channel.
+ */
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled);
+
+/**
+ * qbman_swp_push_set() - Enable or disable push dequeue.
+ * @s: the software portal object.
+ * @channel_idx: the channel index..
+ * @enable: enable or disable push dequeue.
+ *
+ * The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable);
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+/**
+ * struct qbman_pull_desc - the structure for pull dequeue descriptor
+ * @dont_manipulate_directly: the 6 32bit data to represent the whole
+ * possible settings for pull dequeue descriptor.
+ */
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+enum qbman_pull_type_e {
+ /* dequeue with priority precedence, respect intra-class scheduling */
+ qbman_pull_type_prio = 1,
+ /* dequeue with active FQ precedence, respect ICS */
+ qbman_pull_type_active,
+ /* dequeue with active FQ precedence, no ICS */
+ qbman_pull_type_active_noics
+};
+
+/**
+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the pull dequeue descriptor to be cleared.
+ */
+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
+
+/**
+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
+ * @d: the pull dequeue descriptor to be set.
+ * @storage: the pointer of the memory to store the dequeue result.
+ * @storage_phys: the physical address of the storage memory.
+ * @stash: to indicate whether write allocate is enabled.
+ *
+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute.
+ */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/**
+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued.
+ * @d: the pull dequeue descriptor to be set.
+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive.
+ */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
+ uint8_t numframes);
+/**
+ * qbman_pull_desc_set_token() - Set dequeue token for pull command
+ * @d: the dequeue descriptor
+ * @token: the token to be set
+ *
+ * token is the value that shows up in the dequeue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing a dequeue, and use any non-zero 'token' value
+ */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+/**
+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues.
+ * @fqid: the frame queue index of the given FQ.
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid);
+
+/**
+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues.
+ * @wqid: composed of channel id and wqid within the channel.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct);
+
+/* qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
+ * dequeues.
+ * @chid: the channel id to be dequeued.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct);
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object.
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls.
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry.
+ * @s: the software portal object.
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *p);
+
+/**
+ * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
+ * qbman_swp_dqrr_next().
+ * @s: the software portal object.
+ * @dq: the DQRR entry to be consumed.
+ */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct qbman_result *dq);
+
+/**
+ * qbman_get_dqrr_idx() - Get dqrr index from the given dqrr
+ * @dqrr: the given dqrr object.
+ *
+ * Return dqrr index.
+ */
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr);
+
+/**
+ * qbman_get_dqrr_from_idx() - Use index to get the dqrr entry from the
+ * given portal
+ * @s: the given portal.
+ * @idx: the dqrr index.
+ *
+ * Return dqrr entry object.
+ */
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/**
+ * qbman_result_has_new_result() - Check and get the dequeue response from the
+ * dq storage memory set in pull dequeue command
+ * @s: the software portal object.
+ * @dq: the dequeue result read from the memory.
+ *
+ * Only used for user-provided storage of dequeue results, not DQRR. For
+ * efficiency purposes, the driver will perform any required endianness
+ * conversion to ensure that the user's dequeue result storage is in host-endian
+ * format (whether or not that is the same as the little-endian format that
+ * hardware DMA'd to the user's storage). As such, once the user has called
+ * qbman_result_has_new_result() and been returned a valid dequeue result,
+ * they should not call it again on the same memory location (except of course
+ * if another dequeue command has been executed to produce a new result to that
+ * location).
+ *
+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
+ * dequeue result.
+ */
+int qbman_result_has_new_result(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/**
+ * qbman_result_is_DQ() - check the dequeue result is a dequeue response or not
+ * @dq: the dequeue result to be checked.
+ *
+ * DQRR entries may contain non-dequeue results, ie. notifications
+ */
+int qbman_result_is_DQ(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
+ * @dq: the dequeue result to be checked.
+ *
+ * All the non-dequeue results (FQDAN/CDAN/CSCN/...) are "state change
+ * notifications" of one type or another. Some APIs apply to all of them, of the
+ * form qbman_result_SCN_***().
+ */
+static inline int qbman_result_is_SCN(const struct qbman_result *dq)
+{
+ return !qbman_result_is_DQ(dq);
+}
+
+/* Recognise different notification types, only required if the user allows for
+ * these to occur, and cares about them when they do.
+ */
+
+/**
+ * qbman_result_is_FQDAN() - Check for FQ Data Availability
+ * @dq: the qbman_result object.
+ *
+ * Return 1 if this is FQDAN.
+ */
+int qbman_result_is_FQDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CDAN() - Check for Channel Data Availability
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CDAN.
+ */
+int qbman_result_is_CDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CSCN() - Check for Congestion State Change
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CSCN.
+ */
+int qbman_result_is_CSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_BPSCN() - Check for Buffer Pool State Change.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is BPSCN.
+ */
+int qbman_result_is_BPSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CGCU() - Check for Congestion Group Count Update.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CGCU.
+ */
+int qbman_result_is_CGCU(const struct qbman_result *dq);
+
+/* Frame queue state change notifications; (FQDAN in theory counts too as it
+ * leaves a FQ parked, but it is primarily a data availability notification)
+ */
+
+/**
+ * qbman_result_is_FQRN() - Check for FQ Retirement Notification.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRN.
+ */
+int qbman_result_is_FQRN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQRNI() - Check for FQ Retirement Immediate
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRNI.
+ */
+int qbman_result_is_FQRNI(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQPN() - Check for FQ Park Notification
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQPN.
+ */
+int qbman_result_is_FQPN(const struct qbman_result *dq);
+
+/* Parsing frame dequeue results (qbman_result_is_DQ() must be TRUE)
+ */
+/* FQ empty */
+#define QBMAN_DQ_STAT_FQEMPTY 0x80
+/* FQ held active */
+#define QBMAN_DQ_STAT_HELDACTIVE 0x40
+/* FQ force eligible */
+#define QBMAN_DQ_STAT_FORCEELIGIBLE 0x20
+/* Valid frame */
+#define QBMAN_DQ_STAT_VALIDFRAME 0x10
+/* FQ ODP enable */
+#define QBMAN_DQ_STAT_ODPVALID 0x04
+/* Volatile dequeue */
+#define QBMAN_DQ_STAT_VOLATILE 0x02
+/* volatile dequeue command is expired */
+#define QBMAN_DQ_STAT_EXPIRED 0x01
+
+/**
+ * qbman_result_DQ_flags() - Get the STAT field of dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the state field.
+ */
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_is_pull() - Check whether the dq response is from a pull
+ * command.
+ * @dq: the dequeue result.
+ *
+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
+ */
+static inline int qbman_result_DQ_is_pull(const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_VOLATILE);
+}
+
+/**
+ * qbman_result_DQ_is_pull_complete() - Check whether the pull command is
+ * completed.
+ * @dq: the dequeue result.
+ *
+ * Return boolean.
+ */
+static inline int qbman_result_DQ_is_pull_complete(
+ const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_EXPIRED);
+}
+
+/**
+ * qbman_result_DQ_seqnum() - Get the seqnum field in dequeue response
+ * seqnum is valid only if VALIDFRAME flag is TRUE
+ * @dq: the dequeue result.
+ *
+ * Return seqnum.
+ */
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_odpid() - Get the seqnum field in dequeue response
+ * odpid is valid only if ODPVAILD flag is TRUE.
+ * @dq: the dequeue result.
+ *
+ * Return odpid.
+ */
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqid() - Get the fqid in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return fqid.
+ */
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_byte_count() - Get the byte count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the byte count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_frame_count - Get the frame count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqd_ctx() - Get the frame queue context in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame queue context.
+ */
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fd() - Get the frame descriptor in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame descriptor.
+ */
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq);
+
+/* State-change notifications (FQDAN/CDAN/CSCN/...). */
+
+/**
+ * qbman_result_SCN_state() - Get the state field in State-change notification
+ * @scn: the state change notification.
+ *
+ * Return the state in the notifiation.
+ */
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid() - Get the resource id from the notification
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_ctx() - get the context from the notification
+ * @scn: the state change notification.
+ *
+ * Return the context.
+ */
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_state_in_mem() - Get the state in notification written
+ * in memory
+ * @scn: the state change notification.
+ *
+ * Return the state.
+ */
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid_in_mem() - Get the resource id in notification written
+ * in memory.
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn);
+
+/* Type-specific "resource IDs". Mainly for illustration purposes, though it
+ * also gives the appropriate type widths.
+ */
+/* Get the FQID from the FQDAN */
+#define qbman_result_FQDAN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRN */
+#define qbman_result_FQRN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRNI */
+#define qbman_result_FQRNI_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQPN */
+#define qbman_result_FQPN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the channel ID from the CDAN */
+#define qbman_result_CDAN_cid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+/* Get the CGID from the CSCN */
+#define qbman_result_CSCN_cgid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+
+/**
+ * qbman_result_bpscn_bpid() - Get the bpid from BPSCN
+ * @scn: the state change notification.
+ *
+ * Return the buffer pool id.
+ */
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_has_free_bufs() - Check whether there are free
+ * buffers in the pool from BPSCN.
+ * @scn: the state change notification.
+ *
+ * Return the number of free buffers.
+ */
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_depleted() - Check BPSCN to see whether the
+ * buffer pool is depleted.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool depletion.
+ */
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_surplus() - Check BPSCN to see whether the buffer
+ * pool is surplus or not.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool surplus.
+ */
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_ctx() - Get the BPSCN CTX from BPSCN message
+ * @scn: the state change notification.
+ *
+ * Return the BPSCN context.
+ */
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn);
+
+/* Parsing CGCU */
+/**
+ * qbman_result_cgcu_cgid() - Check CGCU resouce id, i.e. cgid
+ * @scn: the state change notification.
+ *
+ * Return the CGCU resource id.
+ */
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_cgcu_icnt() - Get the I_CNT from CGCU
+ * @scn: the state change notification.
+ *
+ * Return instantaneous count in the CGCU notification.
+ */
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+/**
+ * struct qbman_eq_desc - structure of enqueue descriptor
+ * @dont_manipulate_directly: the 8 32bit data to represent the whole
+ * possible qbman enqueue setting in enqueue descriptor.
+ */
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+/**
+ * struct qbman_eq_response - structure of enqueue response
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * enqueue response.
+ */
+struct qbman_eq_response {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/**
+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the given enqueue descriptor.
+ */
+void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+
+/**
+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+/**
+ * qbman_eq_desc_set_orp() - Set order-resotration in the enqueue descriptor
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ * @incomplete: indiates whether this is the last fragments using the same
+ * sequeue number.
+ */
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete);
+
+/**
+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+
+/**
+ * qbman_eq_desc_set_orp_nesn() - advance NESN (Next Expected Sequence Number)
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+/**
+ * qbman_eq_desc_set_response() - Set the enqueue response info.
+ * @d: the enqueue descriptor
+ * @storage_phys: the physical address of the enqueue response in memory.
+ * @stash: indicate that the write allocation enabled or not.
+ *
+ * In the case where an enqueue response is DMA'd, this determines where that
+ * response should go. (The physical/DMA address is given for hardware's
+ * benefit, but software should interpret it as a "struct qbman_eq_response"
+ * data structure.) 'stash' controls whether or not the write to main-memory
+ * expresses a cache-warming attribute.
+ */
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash);
+
+/**
+ * qbman_eq_desc_set_token() - Set token for the enqueue command
+ * @d: the enqueue descriptor
+ * @token: the token to be set.
+ *
+ * token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value.
+ */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token);
+
+/**
+ * Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+/**
+ * qbman_eq_desc_set_fq() - Set Frame Queue id for the enqueue command
+ * @d: the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued.
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid);
+
+/**
+ * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command.
+ * @d: the enqueue descriptor
+ * @qdid: the id of the queuing destination to be enqueued.
+ * @qd_bin: the queuing destination bin
+ * @qd_prio: the queuing destination priority.
+ */
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/**
+ * qbman_eq_desc_set_eqdi() - enable/disable EQDI interrupt
+ * @d: the enqueue descriptor
+ * @enable: boolean to enable/disable EQDI
+ *
+ * Determines whether or not the portal's EQDI interrupt source should be
+ * asserted after the enqueue command is completed.
+ */
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable);
+
+/**
+ * qbman_eq_desc_set_dca() - Set DCA mode in the enqueue command.
+ * @d: the enqueue descriptor.
+ * @enable: enabled/disable DCA mode.
+ * @dqrr_idx: DCAP_CI, the DCAP consumer index.
+ * @park: determine the whether park the FQ or not
+ *
+ * Determines whether or not a portal DQRR entry should be consumed once the
+ * enqueue command is completed. (And if so, and the DQRR entry corresponds to a
+ * held-active (order-preserving) FQ, whether the FQ should be parked instead of
+ * being rescheduled.)
+ */
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park);
+
+/**
+ * qbman_swp_enqueue() - Issue an enqueue command.
+ * @s: the software portal used for enqueue.
+ * @d: the enqueue descriptor.
+ * @fd: the frame descriptor to be enqueued.
+ *
+ * Please note that 'fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".
+ *
+ * Return 0 for a successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd);
+
+/* TODO:
+ * qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt.
+ * @s: the software portal.
+ * @thresh: the threshold to trigger the EQRI interrupt.
+ *
+ * An EQRI interrupt can be generated when the fill-level of EQCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_enqueue_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+/**
+ * struct qbman_release_desc - The structure for buffer release descriptor
+ * @dont_manipulate_directly: the 32bit data to represent the whole
+ * possible settings of qbman release descriptor.
+ */
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/**
+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_clear(struct qbman_release_desc *d);
+
+/**
+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid);
+
+/**
+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
+ * interrupt source should be asserted after the release command is completed.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+
+/**
+ * qbman_swp_release() - Issue a buffer release command.
+ * @s: the software portal object.
+ * @d: the release descriptor.
+ * @buffers: a pointer pointing to the buffer address to be released.
+ * @num_buffers: number of buffers to be released, must be less than 8.
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+/* TODO:
+ * qbman_swp_release_thresh() - Set threshold for RCRI interrupt
+ * @s: the software portal.
+ * @thresh: the threshold.
+ * An RCRI interrupt can be generated when the fill-level of RCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_release_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+/**
+ * qbman_swp_acquire() - Issue a buffer acquire command.
+ * @s: the software portal object.
+ * @bpid: the buffer pool index.
+ * @buffers: a pointer pointing to the acquired buffer address|es.
+ * @num_buffers: number of buffers to be acquired, must be less than 8.
+ *
+ * Return 0 for success, or negative error code if the acquire command
+ * fails.
+ */
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+
+ /*****************/
+ /* FQ management */
+ /*****************/
+/**
+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be scheduled.
+ *
+ * There are a couple of different ways that a FQ can end up parked state,
+ * This schedules it.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be forced.
+ *
+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
+ * and thus be available for selection by any channel-dequeuing behaviour (push
+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
+ * empty at the time this happens, the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * These functions change the FQ flow-control stuff between XON/XOFF. (The
+ * default is XON.) This setting doesn't affect enqueues to the FQ, just
+ * dequeues. XOFF FQs will remain in the tenatively-scheduled state, even when
+ * non-empty, meaning they won't be selected for scheduled dequeuing. If a FQ is
+ * changed to XOFF after it had already become truly-scheduled to a channel, and
+ * a pull dequeue of that channel occurs that selects that FQ for dequeuing,
+ * then the resulting dq_entry will have no FD. (qbman_result_DQ_fd() will
+ * return NULL.)
+ */
+/**
+ * qbman_swp_fq_xon() - XON the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid);
+/**
+ * qbman_swp_fq_xoff() - XOFF the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid);
+
+ /**********************/
+ /* Channel management */
+ /**********************/
+
+/**
+ * If the user has been allocated a channel object that is going to generate
+ * CDANs to another channel, then these functions will be necessary.
+ * CDAN-enabled channels only generate a single CDAN notification, after which
+ * it they need to be reenabled before they'll generate another. (The idea is
+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
+ * reenable step.) Each function generates a distinct command to hardware, so a
+ * combination function is provided if the user wishes to modify the "context"
+ * (which shows up in each CDAN message) each time they reenable, as a single
+ * command to hardware.
+ */
+
+/**
+ * qbman_swp_CDAN_set_context() - Set CDAN context
+ * @s: the software portal object.
+ * @channelid: the channel index.
+ * @ctx: the context to be set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+
+/**
+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_disable() - disable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ * @ctx: the context set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ uint8_t burst_index);
+int qbman_swp_flush_ring(struct qbman_swp *s);
+void qbman_sync(void);
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send);
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+int qbman_get_version(void);
+#endif /* !_FSL_QBMAN_PORTAL_H */
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
new file mode 100644
index 0000000..5d407cc
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.c
@@ -0,0 +1,1496 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQCR_PI 0x800
+#define QBMAN_CINH_SWP_EQCR_CI 0x840
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DQPI 0xa00
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+#define QBMAN_CINH_SWP_ISR 0xe00
+#define QBMAN_CINH_SWP_IER 0xe40
+#define QBMAN_CINH_SWP_ISDR 0xe80
+#define QBMAN_CINH_SWP_IIR 0xec0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+#define QBMAN_CENA_SWP_EQCR_CI 0x840
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
+
+/* QBMan FQ management command codes */
+#define QBMAN_FQ_SCHEDULE 0x48
+#define QBMAN_FQ_FORCE 0x49
+#define QBMAN_FQ_XON 0x4d
+#define QBMAN_FQ_XOFF 0x4e
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init()
+ */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_eq_dca_idx;
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+struct qb_attr_code code_sdqcr_dqsrc = QB_CODE(0, 0, 16);
+
+/* We need to keep track of which SWP triggered a pull command
+ * so keep an array of portal IDs and use the token field to
+ * be able to find the proper portal
+ */
+#define MAX_QBMAN_PORTALS 35
+static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
+
+uint32_t qman_version;
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has.
+ *
+ * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
+ * valid-bits, so we need to support a workaround where we don't trust
+ * valid-bits when detecting new entries until any stale ring entries have been
+ * overwritten at least once. The idea is that we read PI for the first few
+ * entries, then switch to valid-bit after that. The trick is to clear the
+ * bug-work-around boolean once the PI wraps around the ring for the first time.
+ *
+ * Note: this still carries a slight additional cost once the decrementer hits
+ * zero.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ uint32_t eqcr_pi;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = *d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
+ atomic_set(&p->vdq.busy, 1);
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ qman_version = p->desc.qman_version;
+ if ((qman_version & 0xFFFF0000) < QMAN_REV_4100) {
+ p->dqrr.dqrr_size = 4;
+ p->dqrr.reset_bug = 1;
+ /* Set size of DQRR to 4, encoded in 2 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 2);
+ } else {
+ p->dqrr.dqrr_size = 8;
+ p->dqrr.reset_bug = 0;
+ /* Set size of DQRR to 8, encoded in 3 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 3);
+ }
+
+ ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
+ if (ret) {
+ kfree(p);
+ pr_err("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ /* SDQCR needs to be initialized to 0 when no channels are
+ * being dequeued from or else the QMan HW will indicate an
+ * error. The values that were calculated above will be
+ * applied when dequeues from a specific channel are enabled
+ */
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
+ eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
+ p->eqcr.pi = eqcr_pi & 0xF;
+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
+ p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & 0xF;
+ p->eqcr.available = QBMAN_EQCR_SIZE - qm_cyc_diff(QBMAN_EQCR_SIZE,
+ p->eqcr.ci, p->eqcr.pi);
+
+ portal_idx_map[p->desc.idx] = p;
+ return p;
+}
+
+void qbman_swp_finish(struct qbman_swp *p)
+{
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ qbman_swp_sys_finish(&p->sys);
+ portal_idx_map[p->desc.idx] = NULL;
+ kfree(p);
+}
+
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
+{
+ return &p->desc;
+}
+
+/**************/
+/* Interrupts */
+/**************/
+
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
+}
+
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
+}
+
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
+}
+
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
+}
+
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
+}
+
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
+}
+
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
+}
+
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
+#endif
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so.
+ */
+ QBMAN_BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ qbman_cena_invalidate_prefetch(&p->sys,
+ QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_eqdi = QB_CODE(0, 3, 1);
+static struct qb_attr_code code_eq_dca_en = QB_CODE(0, 15, 1);
+static struct qb_attr_code code_eq_dca_pk = QB_CODE(0, 14, 1);
+/* Can't set code_eq_dca_idx width. Need qman version. Read at runtime */
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_orp_is_nesn = QB_CODE(0, 31, 1);
+static struct qb_attr_code code_eq_orp_nlis = QB_CODE(0, 30, 1);
+static struct qb_attr_code code_eq_orp_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_eq_opr_id = QB_CODE(1, 0, 16);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
+static struct qb_attr_code code_eq_rsp_id = QB_CODE(5, 24, 8);
+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
+
+enum qbman_eq_cmd_e {
+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, !!incomplete);
+}
+
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 0);
+}
+
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 1);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
+}
+
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_rsp_id, cl, (uint32_t)token);
+}
+
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 0);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, fqid);
+}
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_eqdi, cl, !!enable);
+}
+
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_dca_en, cl, !!enable);
+ if (enable) {
+ qb_attr_code_encode(&code_eq_dca_pk, cl, !!park);
+ qb_attr_code_encode(&code_eq_dca_idx, cl, dqrr_idx);
+ }
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+
+ pr_debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ return 0;
+}
+
+static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ return 0;
+}
+
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ __attribute__((unused)) uint8_t burst_index)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR((s->eqcr.pi/* +burst_index */) & 7));
+ /* word_copy(&p[1], &cl[1], 7); */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ /* word_copy(&p[8], fd, sizeof(*fd) >> 2); */
+ memcpy(&p[8], fd, sizeof(struct qbman_fd));
+
+ /* lwsync(); */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+
+ return 0;
+}
+
+int qbman_swp_flush_ring(struct qbman_swp *s)
+{
+ void *ptr = s->sys.addr_cena;
+
+ dcbf((uint64_t)ptr);
+ dcbf((uint64_t)ptr + 0x40);
+ dcbf((uint64_t)ptr + 0x80);
+ dcbf((uint64_t)ptr + 0xc0);
+ dcbf((uint64_t)ptr + 0x100);
+ dcbf((uint64_t)ptr + 0x140);
+ dcbf((uint64_t)ptr + 0x180);
+ dcbf((uint64_t)ptr + 0x1c0);
+
+ return 0;
+}
+
+void qbman_sync(void)
+{
+ lwsync();
+}
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ if (s->sys.eqcr_mode == qman_eqcr_vb_array)
+ return qbman_swp_enqueue_array_mode(s, d, fd);
+ else /* Use ring mode by default */
+ return qbman_swp_enqueue_ring_mode(s, d, fd);
+}
+
+/*************************/
+/* Static (push) dequeue */
+/*************************/
+
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
+{
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ *enabled = (int)qb_attr_code_decode(&code, &s->sdq);
+}
+
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
+{
+ uint16_t dqsrc;
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ qb_attr_code_encode(&code, &s->sdq, !!enable);
+ /* Read make the complete src map. If no channels are enabled
+ * the SDQCR must be 0 or else QMan will assert errors
+ */
+ dqsrc = (uint16_t)qb_attr_code_decode(&code_sdqcr_dqsrc, &s->sdq);
+ if (dqsrc != 0)
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
+ else
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
+
+enum qb_pull_dt_e {
+ qb_pull_dt_channel,
+ qb_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command)
+ */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ qb_attr_code_encode(&code_pull_rls, cl, 1);
+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ QBMAN_BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_workqueue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, wqid);
+}
+
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_channel);
+ qb_attr_code_encode(&code_pull_dqsource, cl, chid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
+ return -EBUSY;
+ }
+ s->vdq.storage = *(void **)&cl[4];
+ /* We use portal index +1 as token so that 0 still indicates
+ * that the result isn't valid yet.
+ */
+ qb_attr_code_encode(&code_pull_token, cl, s->desc.idx + 1);
+ p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ word_copy(&p[1], &cl[1], 3);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+static struct qb_attr_code code_dqrr_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_dqrr_odpid = QB_CODE(1, 0, 16);
+/* static struct qb_attr_code code_dqrr_tok = QB_CODE(1, 24, 8); */
+static struct qb_attr_code code_dqrr_fqid = QB_CODE(2, 0, 24);
+static struct qb_attr_code code_dqrr_byte_count = QB_CODE(4, 0, 32);
+static struct qb_attr_code code_dqrr_frame_count = QB_CODE(5, 0, 24);
+static struct qb_attr_code code_dqrr_ctx_lo = QB_CODE(6, 0, 32);
+
+#define QBMAN_RESULT_DQ 0x60
+#define QBMAN_RESULT_FQRN 0x21
+#define QBMAN_RESULT_FQRNI 0x22
+#define QBMAN_RESULT_FQPN 0x24
+#define QBMAN_RESULT_FQDAN 0x25
+#define QBMAN_RESULT_CDAN 0x26
+#define QBMAN_RESULT_CSCN_MEM 0x27
+#define QBMAN_RESULT_CGCU 0x28
+#define QBMAN_RESULT_BPSCN 0x29
+#define QBMAN_RESULT_CSCN_WQ 0x2a
+
+static struct qb_attr_code code_dqpi_pi = QB_CODE(0, 0, 4);
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ uint32_t verb;
+ uint32_t response_verb;
+ uint32_t flags;
+ const struct qbman_result *dq;
+ const uint32_t *p;
+
+ /* Before using valid-bit to detect if something is there, we have to
+ * handle the case of the DQRR reset bug...
+ */
+ if (unlikely(s->dqrr.reset_bug)) {
+ /* We pick up new entries by cache-inhibited producer index,
+ * which means that a non-coherent mapping would require us to
+ * invalidate and read *only* once that PI has indicated that
+ * there's an entry here. The first trip around the DQRR ring
+ * will be much less efficient than all subsequent trips around
+ * it...
+ */
+ uint32_t dqpi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI);
+ uint32_t pi = qb_attr_code_decode(&code_dqpi_pi, &dqpi);
+ /* there are new entries iff pi != next_idx */
+ if (pi == s->dqrr.next_idx)
+ return NULL;
+ /* if next_idx is/was the last ring index, and 'pi' is
+ * different, we can disable the workaround as all the ring
+ * entries have now been DMA'd to so valid-bit checking is
+ * repaired. Note: this logic needs to be based on next_idx
+ * (which increments one at a time), rather than on pi (which
+ * can burst and wrap-around between our snapshots of it).
+ */
+ QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
+ pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
+ s->dqrr.next_idx, pi);
+ s->dqrr.reset_bug = 0;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ }
+ dq = qbman_cena_read_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
+ return NULL;
+
+ /* There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found.
+ */
+ s->dqrr.next_idx++;
+ if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
+ s->dqrr.next_idx = 0;
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+ }
+ /* If this is the final response to a volatile dequeue command
+ * indicate that the vdq is no longer busy.
+ */
+ flags = qbman_result_DQ_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_RESULT_DQ) &&
+ (flags & QBMAN_DQ_STAT_VOLATILE) &&
+ (flags & QBMAN_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+int qbman_result_has_new_result(__attribute__((unused)) struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* Entry is valid - overwrite token back to 0 so
+ * a) If this memory is reused tokesn will be 0
+ * b) If someone calls "has_new_result()" again on this entry it
+ * will not appear to be new
+ */
+ qb_attr_code_encode(&code_dqrr_tok_detect, &p[1], 0);
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice...
+ */
+ make_le32_n(p, 16);
+ return 1;
+}
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* TODO: Remove qbman_swp from parameters and make it a local
+ * once we've tested the reserve portal map change
+ */
+ s = portal_idx_map[token - 1];
+ /* When token is set it indicates that VDQ command has been fetched
+ * by qbman and is working on it. It is safe for software to issue
+ * another VDQ command, so incrementing the busy variable.
+ */
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
+ return 1;
+}
+
+/********************************/
+/* Categorising qbman results */
+/********************************/
+
+static struct qb_attr_code code_result_in_mem =
+ QB_CODE(0, QBMAN_RESULT_VERB_OFFSET_IN_MEM, 7);
+
+static inline int __qbman_result_is_x(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return (response_verb == x);
+}
+
+static inline int __qbman_result_is_x_in_mem(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_result_in_mem, p);
+
+ return (response_verb == x);
+}
+
+int qbman_result_is_DQ(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
+}
+
+int qbman_result_is_FQDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
+}
+
+int qbman_result_is_CDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
+}
+
+int qbman_result_is_CSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CSCN_MEM) ||
+ __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
+}
+
+int qbman_result_is_BPSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_BPSCN);
+}
+
+int qbman_result_is_CGCU(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CGCU);
+}
+
+int qbman_result_is_FQRN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRN);
+}
+
+int qbman_result_is_FQRNI(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRNI);
+}
+
+int qbman_result_is_FQPN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_result_is_DQ() is TRUE */
+
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_seqnum, p);
+}
+
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_odpid, p);
+}
+
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_fqid, p);
+}
+
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_byte_count, p);
+}
+
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_frame_count, p);
+}
+
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(dq);
+
+ return qb_attr_code_decode_64(&code_dqrr_ctx_lo, p);
+}
+
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct qbman_fd *)&p[8];
+}
+
+/**************************************/
+/* Parsing state-change notifications */
+/**************************************/
+
+static struct qb_attr_code code_scn_state = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_scn_rid = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_scn_state_in_mem =
+ QB_CODE(0, SCN_STATE_OFFSET_IN_MEM, 8);
+static struct qb_attr_code code_scn_rid_in_mem =
+ QB_CODE(1, SCN_RID_OFFSET_IN_MEM, 24);
+static struct qb_attr_code code_scn_ctx_lo = QB_CODE(2, 0, 32);
+
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state, p);
+}
+
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return qb_attr_code_decode(&code_scn_rid, p);
+}
+
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(scn);
+
+ return qb_attr_code_decode_64(&code_scn_ctx_lo, p);
+}
+
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state_in_mem, p);
+}
+
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+ uint32_t result_rid;
+
+ result_rid = qb_attr_code_decode(&code_scn_rid_in_mem, p);
+ return make_le24(result_rid);
+}
+
+/*****************/
+/* Parsing BPSCN */
+/*****************/
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0x3FFF;
+}
+
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
+{
+ return !(int)(qbman_result_SCN_state_in_mem(scn) & 0x1);
+}
+
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x2);
+}
+
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x4);
+}
+
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)make_le32(ctx_hi) << 32 |
+ (uint64_t)make_le32(ctx_lo));
+}
+
+/*****************/
+/* Parsing CGCU */
+/*****************/
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0xFFFF;
+}
+
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)(make_le32(ctx_hi) & 0xFF) << 32) |
+ (uint64_t)make_le32(ctx_lo);
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_rcdi = QB_CODE(0, 6, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_rcdi, cl, !!enable);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+
+ pr_debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers.
+ */
+ lwsync();
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t rslt, num;
+
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) !=
+ QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ QBMAN_BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
+
+/*****************/
+/* FQ management */
+/*****************/
+
+static struct qb_attr_code code_fqalt_fqid = QB_CODE(1, 0, 32);
+
+static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
+ uint8_t alt_fq_verb)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ qb_attr_code_encode(&code_fqalt_fqid, p, fqid);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | alt_fq_verb);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != alt_fq_verb);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
+ fqid, alt_fq_verb, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
+}
+
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
+}
+
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
+}
+
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
+}
+
+/**********************/
+/* Channel management */
+/**********************/
+
+static struct qb_attr_code code_cdan_cid = QB_CODE(0, 16, 12);
+static struct qb_attr_code code_cdan_we = QB_CODE(1, 0, 8);
+static struct qb_attr_code code_cdan_en = QB_CODE(1, 8, 1);
+static struct qb_attr_code code_cdan_ctx_lo = QB_CODE(2, 0, 32);
+
+/* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
+ * would be irresponsible to expose it.
+ */
+#define CODE_CDAN_WE_EN 0x1
+#define CODE_CDAN_WE_CTX 0x4
+
+static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
+ uint8_t we_mask, uint8_t cdan_en,
+ uint64_t ctx)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_cdan_cid, p, channelid);
+ qb_attr_code_encode(&code_cdan_we, p, we_mask);
+ qb_attr_code_encode(&code_cdan_en, p, cdan_en);
+ qb_attr_code_encode_64(&code_cdan_ctx_lo, (uint64_t *)p, ctx);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_WQCHAN_CONFIGURE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p)
+ != QBMAN_WQCHAN_CONFIGURE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("CDAN cQID %d failed: code = 0x%02x\n",
+ channelid, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_CTX,
+ 0, ctx);
+}
+
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 1, 0);
+}
+
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 0, 0);
+}
+
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
+ 1, ctx);
+}
+
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr)
+{
+ return QBMAN_IDX_FROM_DQRR(dqrr);
+}
+
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
+{
+ struct qbman_result *dq;
+
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
+ return dq;
+}
+
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+ int sent = 0;
+ int i;
+ int initial_pi = s->eqcr.pi;
+ uint64_t start_pointer;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ if (!diff)
+ goto done;
+ s->eqcr.available += diff;
+ }
+
+ /* we are trying to send frames_to_send,
+ * if we have enough space in the ring
+ */
+ while (s->eqcr.available && frames_to_send--) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+ /* Write command (except of first byte) and FD */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ memcpy(&p[8], &fd[sent], sizeof(struct qbman_fd));
+
+ initial_pi++;
+ initial_pi &= 0xF;
+ s->eqcr.available--;
+ sent++;
+ }
+
+done:
+ initial_pi = s->eqcr.pi;
+ lwsync();
+
+ /* in order for flushes to complete faster:
+ * we use a following trick: we record all lines in 32 bit word
+ */
+
+ initial_pi = s->eqcr.pi;
+ for (i = 0; i < sent; i++) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ initial_pi++;
+ initial_pi &= 0xF;
+
+ if (!(initial_pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ initial_pi = s->eqcr.pi;
+
+ /* We need to flush all the lines but without
+ * load/store operations between them.
+ * We assign start_pointer before we start loop so that
+ * in loop we do not read it from memory
+ */
+ start_pointer = (uint64_t)s->sys.addr_cena;
+ for (i = 0; i < sent; i++) {
+ p = (uint32_t *)(start_pointer
+ + QBMAN_CENA_SWP_EQCR(initial_pi & 7));
+ dcbf((uint64_t)p);
+ initial_pi++;
+ initial_pi &= 0xF;
+ }
+
+ /* Update producer index for the next call */
+ s->eqcr.pi = initial_pi;
+
+ return sent;
+}
+
+int qbman_get_version(void)
+{
+ return qman_version;
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.h b/drivers/common/dpaa2/qbman/qbman_portal.h
new file mode 100644
index 0000000..7aa1d4f
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_portal.h
@@ -0,0 +1,277 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_private.h"
+#include <fsl_qbman_portal.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* QBMan DQRR size is set at runtime in qbman_portal.c */
+
+#define QBMAN_EQCR_SIZE 8
+
+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return last - first;
+ return (2 * ringsize) + last - first;
+}
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ struct qbman_swp_desc desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here.
+ */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * to whether or not a command can be submitted, not whether or
+ * not a previously-submitted command is still executing. In
+ * other words, once proof is seen that the previously-submitted
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ /* We need to determine when vdq is no longer busy. This depends
+ * on whether the "busy" (last-submitted) dequeue command is
+ * targeting DQRR or main-memory, and detected is based on the
+ * presence of the dequeue command's "token" showing up in
+ * dequeue entries in DQRR or main-memory (respectively).
+ */
+ struct qbman_result *storage; /* NULL if DQRR */
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ uint8_t dqrr_size;
+ int reset_bug;
+ } dqrr;
+ struct {
+ uint32_t pi;
+ uint32_t pi_vb;
+ uint32_t ci;
+ int available;
+ } eqcr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete).
+ */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and DPAA2 QBMan is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Some pre-defined codes */
+extern struct qb_attr_code code_generic_verb;
+extern struct qb_attr_code code_generic_rslt;
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+#define QB_CODE_NULL \
+ QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
+
+/* Rotate a code "ms", meaning that it moves from less-significant bytes to
+ * more-significant, from less-significant words to more-significant, etc. The
+ * "ls" version does the inverse, from more-significant towards
+ * less-significant.
+ */
+static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ code->lsoffset += bits;
+ while (code->lsoffset > 31) {
+ code->word++;
+ code->lsoffset -= 32;
+ }
+}
+
+static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ /* Don't be fooled, this trick should work because the types are
+ * unsigned. So the case that interests the while loop (the rotate has
+ * gone too far and the word count needs to compensate for it), is
+ * manifested when lsoffset is negative. But that equates to a really
+ * large unsigned value, starting with lots of "F"s. As such, we can
+ * continue adding 32 back to it until it wraps back round above zero,
+ * to a value of 31 or less...
+ */
+ code->lsoffset -= bits;
+ while (code->lsoffset > 31) {
+ code->word--;
+ code->lsoffset += 32;
+ }
+}
+
+/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
+#define qb_attr_code_for_ms(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ms(code, bits))
+#define qb_attr_code_for_ls(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ls(code, bits))
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
+}
+
+static inline uint64_t qb_attr_code_decode_64(const struct qb_attr_code *code,
+ const uint64_t *cacheline)
+{
+ return cacheline[code->word / 2];
+}
+
+/* encode a field to a cacheline */
+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
+ uint32_t *cacheline, uint32_t val)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
+/* Small-width signed values (two's-complement) will decode into medium-width
+ * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
+ * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
+ * 249. Likewise -120 would decode as 136.) This function allows the caller to
+ * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
+ * encoding, will become 0xfffffff9 if you cast the return value to uint32_t).
+ */
+static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
+ uint32_t val)
+{
+ QBMAN_BUG_ON(val >= (1u << code->width));
+ /* code->width should never exceed the width of val. If it does then a
+ * different function with larger val size must be used to translate
+ * from unsigned to signed
+ */
+ QBMAN_BUG_ON(code->width > sizeof(val) * CHAR_BIT);
+ /* If the high bit was set, it was encoding a negative */
+ if (val >= 1u << (code->width - 1))
+ return (int32_t)0 - (int32_t)(((uint32_t)1 << code->width) -
+ val);
+ /* Otherwise, it was encoding a positive */
+ return (int32_t)val;
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * a "descriptor" type that the caller can instantiate however they like.
+ * Ultimately though, it is just a cacheline of binary storage (or something
+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
+ * holding pre-formatted pieces of hardware commands. The performance-critical
+ * code can then copy these descriptors directly into hardware command
+ * registers more efficiently than trying to construct/format commands
+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/common/dpaa2/qbman/qbman_private.h b/drivers/common/dpaa2/qbman/qbman_private.h
new file mode 100644
index 0000000..f5fa13d
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_private.h
@@ -0,0 +1,170 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+/* Perform extra checking */
+#define QBMAN_CHECKING
+
+/* To maximise the amount of logic that is common between the Linux driver and
+ * other targets (such as the embedded MC firmware), we pivot here between the
+ * inclusion of two platform-specific headers.
+ *
+ * The first, qbman_sys_decl.h, includes any and all required system headers as
+ * well as providing any definitions for the purposes of compatibility. The
+ * second, qbman_sys.h, is where platform-specific routines go.
+ *
+ * The point of the split is that the platform-independent code (including this
+ * header) may depend on platform-specific declarations, yet other
+ * platform-specific routines may depend on platform-independent definitions.
+ */
+
+#include "qbman_sys_decl.h"
+
+/* When things go wrong, it is a convenient trick to insert a few FOO()
+ * statements in the code to trace progress. TODO: remove this once we are
+ * hacking the code less actively.
+ */
+#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+do { \
+ if (!(loopvar--)) \
+ QBMAN_BUG_ON(NULL == "DBG_POLL_CHECK"); \
+} while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ pr_info("%s", buf);
+ }
+}
+
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#include "qbman_sys.h"
diff --git a/drivers/common/dpaa2/qbman/qbman_sys.h b/drivers/common/dpaa2/qbman/qbman_sys.h
new file mode 100644
index 0000000..5dbcaa5
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys.h
@@ -0,0 +1,385 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required.
+ */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness.
+ */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+
+static inline uint32_t make_le24(uint32_t val)
+{
+ return (((val & 0xff) << 16) | (val & 0xff00) |
+ ((val & 0xff0000) >> 16));
+}
+
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+#else
+#define make_le32(val) (val)
+#define make_le24(val) (val)
+#define make_le32_n(val, len) do {} while (0)
+#endif
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder.
+ */
+ uint8_t *cena;
+ uint8_t __iomem *addr_cena;
+ uint8_t __iomem *addr_cinh;
+ uint32_t idx;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void *qbman_cena_write_start_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 1; loop--)
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+ lwsync();
+ __raw_writel(shadow[0], s->addr_cena + offset);
+ dcbf(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+ hexdump(cmd, 64);
+#endif
+ dcbf(s->addr_cena + offset);
+}
+
+static inline uint32_t qbman_cena_read_reg(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ return __raw_readl(s->addr_cena + offset);
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = (uint32_t *)(s->cena + offset);
+ unsigned int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void *qbman_cena_read_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return s->addr_cena + offset;
+}
+
+static inline void qbman_cena_invalidate(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here.
+ */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x2)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x2)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- TRUE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- TRUE)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- TRUE)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- TRUE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) |
+ e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d,
+ uint8_t dqrr_size)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->idx = (uint32_t)d->idx;
+ s->cena = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!s->cena) {
+ pr_err("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+ s->eqcr_mode = d->eqcr_mode;
+ QBMAN_BUG_ON(d->idx < 0);
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ QBMAN_BUG_ON(reg);
+#endif
+ if (s->eqcr_mode == qman_eqcr_vb_array)
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 1, 1, 1, 1,
+ 1, 1);
+ else
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 2, 3, 2, 2, 1, 1, 1, 1,
+ 1, 1);
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ pr_err("The portal %d is not enabled!\n", s->idx);
+ kfree(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free_page((unsigned long)s->cena);
+}
+
+static inline void *
+qbman_cena_write_start_wo_shadow_fast(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
diff --git a/drivers/common/dpaa2/qbman/qbman_sys_decl.h b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
new file mode 100644
index 0000000..e52f5ed
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/qbman_sys_decl.h
@@ -0,0 +1,73 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 <compat.h>
+#include <fsl_qbman_base.h>
+
+/* Sanity check */
+#if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && \
+ (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
+#error "Unknown endianness!"
+#endif
+
+/* The platform-independent code shouldn't need endianness, except for
+ * weird/fast-path cases like qbman_result_has_token(), which needs to
+ * perform a passive and endianness-specific test on a read-only data structure
+ * very quickly. It's an exception, and this symbol is used for that case.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define DQRR_TOK_OFFSET 0
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 24
+#define SCN_STATE_OFFSET_IN_MEM 8
+#define SCN_RID_OFFSET_IN_MEM 8
+#else
+#define DQRR_TOK_OFFSET 24
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 0
+#define SCN_STATE_OFFSET_IN_MEM 16
+#define SCN_RID_OFFSET_IN_MEM 0
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
+#define lwsync() { asm volatile("dmb st" : : : "memory"); }
+#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); }
+#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); }
+static inline void prefetch_for_load(void *p)
+{
+ asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p));
+}
+
+static inline void prefetch_for_store(void *p)
+{
+ asm volatile("prfm pstl1keep, [%0, #64]" : : "r" (p));
+}
diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
new file mode 100644
index 0000000..f653421
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
@@ -0,0 +1,27 @@
+DPDK_17.02 {
+ global:
+
+ qbman_check_command_complete;
+ qbman_eq_desc_clear;
+ qbman_eq_desc_set_fq;
+ qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_qd;
+ qbman_eq_desc_set_response;
+ qbman_get_version;
+ qbman_pull_desc_clear;
+ qbman_pull_desc_set_fq;
+ qbman_pull_desc_set_numframes;
+ qbman_pull_desc_set_storage;
+ qbman_release_desc_clear;
+ qbman_release_desc_set_bpid;
+ qbman_result_DQ_fd;
+ qbman_result_DQ_flags;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
+ qbman_swp_init;
+ qbman_swp_pull;
+ qbman_swp_release;
+ qbman_swp_send_multiple;
+
+ local: *;
+};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-02-16 5:57 ` Shreyansh Jain
2017-02-21 13:42 ` [dpdk-dev] Hello Ferruh, Neil, Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-16 5:57 UTC (permalink / raw)
To: ferruh.yigit
Cc: Hemant Agrawal, dev, thomas.monjalon, bruce.richardson,
john.mcnamara, jerin.jacob
Hello Ferruh,
On Thursday 16 February 2017 06:09 AM, Hemant Agrawal wrote:
> QBMAN, is a hardware block which interfaces with the other
> accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
> SoC for queue, buffer and packet scheduling.
>
> This patch introduces a userspace driver for interfacing with
> the QBMAN hw block.
>
> The qbman-portal component provides APIs to do the low level
> hardware bit twiddling for operations such as:
> -initializing Qman software portals
> -building and sending portal commands
> -portal interrupt configuration and processing
>
> This same/similar code is used in kernel and compat file is used
> to make it working in user space.
>
> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
> Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
[snip]
> diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> new file mode 100644
> index 0000000..f653421
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> @@ -0,0 +1,27 @@
> +DPDK_17.02 {
> + global:
> +
> + qbman_check_command_complete;
> + qbman_eq_desc_clear;
> + qbman_eq_desc_set_fq;
> + qbman_eq_desc_set_no_orp;
> + qbman_eq_desc_set_qd;
> + qbman_eq_desc_set_response;
> + qbman_get_version;
> + qbman_pull_desc_clear;
> + qbman_pull_desc_set_fq;
> + qbman_pull_desc_set_numframes;
> + qbman_pull_desc_set_storage;
> + qbman_release_desc_clear;
> + qbman_release_desc_set_bpid;
> + qbman_result_DQ_fd;
> + qbman_result_DQ_flags;
> + qbman_result_has_new_result;
> + qbman_swp_acquire;
> + qbman_swp_init;
> + qbman_swp_pull;
> + qbman_swp_release;
> + qbman_swp_send_multiple;
> +
> + local: *;
> +};
>
Just wanted to highlight that we have not yet changed the exported
variable in the v7 post. I have a draft patch (based on yours and
Neil's suggestions) which I will share soon.
That involves changing source between our internal repo to dpdk -
feasibility of this is where are discussions internally stand.
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] Hello Ferruh, Neil,
2017-02-16 5:57 ` Shreyansh Jain
@ 2017-02-21 13:42 ` Shreyansh Jain
2017-02-21 13:45 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Shreyansh Jain
` (2 more replies)
0 siblings, 3 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-21 13:42 UTC (permalink / raw)
To: ferruh.yigit; +Cc: dev, nhorman
Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
I create a draft patch for a single symbol change. (applies over v7
of DPAA2 PMD)
Can you tell me if this is the direction you were suggesting?
I see two issues in this approach which are somewhat problematic for
me to change all the symbols:
1) We saw a drop of over 5% when I replaced only 3 symbols (one
of the most used ones, just for sampling). This also means that
when more of such symbols are replaced, it would bring further
drop. This was case when I used the Shared library approach.
(*) I am not well versed with gcc symbol aliasing to comment for
why such a drop would happen. But multiple test cycles confirm
this.
2) I have to include a new header in almost all the source files for PMD/
Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
code. Essentially, any internal repo patch cannot be directly
transposed to DPDK repo. Increased effort for each internal->
external release
Overall, I would like you to consider if this effort for changing names
for exposed symbols is really useful or not.
There is another approach - that of not using a drivers/common library.
This again is problematic for us - NXP DPAA2 being a hardware, the lib
and state for Crypto and Net hardware is tied together - so, having
multiple instances of library breaks either of Crypto or Net PMD.
Any other suggestions?
-
Shreyansh
--->8---
>From b9928ed44e69d7f9f9def0f06647a8d3bc25f284 Mon Sep 17 00:00:00 2001
From: Shreyansh Jain <shreyansh.jain@nxp.com>
Date: Fri, 10 Feb 2017 19:18:55 +0530
Subject: [PATCH] dpaa2: fix for rte_* symbol naming
This sample code:
* creates nxp_compat.h containing custom version of MAP_STATIC_* and
BIND_DEFAULT*
Can't use the existing version because they are based on appending
a string (_v[0-9]), not prepending as required in this case
* creates nxp_shared_symbol.h for appending rte_* to symbols
* declares functions
* changes map file
Hereafter:
* for every newly introduced symbol, create NXP_*_SYMBOL mapping
* put symbol in nxp_shared_symbols.h
* add entry in map with rte_* prepended
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 3 +
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1 +
drivers/common/dpaa2/qbman/include/nxp_compat.h | 70 ++++++++++++++++++++++
.../dpaa2/qbman/include/nxp_shared_symbols.h | 41 +++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 2 +
.../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 2 +-
6 files changed, 118 insertions(+), 1 deletion(-)
create mode 100644 drivers/common/dpaa2/qbman/include/nxp_compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index c80d6c5..1c157b9 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
@@ -59,9 +59,12 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <fsl_qbman_portal.h>
#include "dpaa2_hw_pvt.h"
#include "dpaa2_hw_dpio.h"
+#include <nxp_shared_symbols.h>
+
#define NUM_HOST_CPUS RTE_MAX_LCORE
struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE];
diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
index 7731772..63ffdd1 100644
--- a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
+++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
@@ -29,6 +29,7 @@
#define _FSL_QBMAN_PORTAL_H
#include <fsl_qbman_base.h>
+#include "nxp_compat.h"
/**
* DOC - QBMan portal APIs to implement the following functions:
diff --git a/drivers/common/dpaa2/qbman/include/nxp_compat.h b/drivers/common/dpaa2/qbman/include/nxp_compat.h
new file mode 100644
index 0000000..edbbfde
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/nxp_compat.h
@@ -0,0 +1,70 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2016 NXP
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_COMPAT_H_
+#define _NXP_COMPAT_H_
+#include <rte_common.h>
+
+#ifdef RTE_BUILD_SHARED_LIB
+
+/*
+ * BIND_DEFAULT_SYMBOL
+ * Creates a symbol version entry instructing the linker to bind references to
+ * symbol <b> to exported symbol <a>; it also appends the symbol version as
+ * per the map file.
+ */
+#define NXP_SHARED_SYMBOL(b, a, n) __asm__(".symver " RTE_STR(b) ", " RTE_STR(a) "@@DPDK_" RTE_STR(n))
+
+/*
+ * MAP_STATIC_SYMBOL
+ * If a function has been bifurcated into multiple versions, none of which
+ * are defined as the exported symbol name in the map file, this macro can be
+ * used to alias a specific version of the symbol to its exported name. For
+ * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
+ * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
+ * building a shared library, this macro can be used to map either foo_v1 or
+ * foo_v2 to the symbol foo when building a static library, e.g.:
+ * MAP_STATIC_SYMBOL(void foo(), foo_v2);
+ */
+#define NXP_STATIC_SYMBOL(f, p)
+
+#else
+/*
+ * No symbol versioning in use
+ */
+#define NXP_SHARED_SYMBOL(b, e, n)
+#define NXP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p))))
+/*
+ * RTE_BUILD_SHARED_LIB=n
+ */
+#endif
+
+struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d);
+
+#endif /* _NXP_COMPAT_H_ */
diff --git a/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
new file mode 100644
index 0000000..6faba36
--- /dev/null
+++ b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
@@ -0,0 +1,41 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2016 NXP
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_SHARED_SYMBOLS_H_
+#define _NXP_SHARED_SYMBOLS_H_
+
+#ifdef RTE_BUILD_SHARED_LIB
+
+#define qbman_swp_init rte_qbman_swp_init
+
+#endif
+
+#endif /* NXP_STATIC_SYMBOL */
+
+
diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
index 11116bd..f9bad4f 100644
--- a/drivers/common/dpaa2/qbman/qbman_portal.c
+++ b/drivers/common/dpaa2/qbman/qbman_portal.c
@@ -178,6 +178,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
portal_idx_map[p->desc.idx] = p;
return p;
}
+NXP_SHARED_SYMBOL(qbman_swp_init, rte_qbman_swp_init, 17.02);
+NXP_STATIC_SYMBOL(struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d), qbman_swp_init);
void qbman_swp_finish(struct qbman_swp *p)
{
diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
index f653421..1dda776 100644
--- a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
+++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
@@ -18,7 +18,7 @@ DPDK_17.02 {
qbman_result_DQ_flags;
qbman_result_has_new_result;
qbman_swp_acquire;
- qbman_swp_init;
+ rte_qbman_swp_init;
qbman_swp_pull;
qbman_swp_release;
qbman_swp_send_multiple;
--
2.7.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-21 13:42 ` [dpdk-dev] Hello Ferruh, Neil, Shreyansh Jain
@ 2017-02-21 13:45 ` Shreyansh Jain
2017-02-21 14:39 ` [dpdk-dev] Hello Ferruh, Neil, Ferruh Yigit
2017-02-22 12:41 ` [dpdk-dev] Hello Ferruh, Neil, Neil Horman
2 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-21 13:45 UTC (permalink / raw)
To: ferruh.yigit; +Cc: dev, nhorman
(Modified subject to: "Re: [PATCHv7 03/47] common/dpaa2: adding qbman
driver")
On Tuesday 21 February 2017 07:12 PM, Shreyansh Jain wrote:
> Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
> I create a draft patch for a single symbol change. (applies over v7
> of DPAA2 PMD)
>
> Can you tell me if this is the direction you were suggesting?
>
> I see two issues in this approach which are somewhat problematic for
> me to change all the symbols:
> 1) We saw a drop of over 5% when I replaced only 3 symbols (one
> of the most used ones, just for sampling). This also means that
> when more of such symbols are replaced, it would bring further
> drop. This was case when I used the Shared library approach.
> (*) I am not well versed with gcc symbol aliasing to comment for
> why such a drop would happen. But multiple test cycles confirm
> this.
> 2) I have to include a new header in almost all the source files for PMD/
> Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
> code. Essentially, any internal repo patch cannot be directly
> transposed to DPDK repo. Increased effort for each internal->
> external release
>
> Overall, I would like you to consider if this effort for changing names
> for exposed symbols is really useful or not.
>
> There is another approach - that of not using a drivers/common library.
> This again is problematic for us - NXP DPAA2 being a hardware, the lib
> and state for Crypto and Net hardware is tied together - so, having
> multiple instances of library breaks either of Crypto or Net PMD.
>
> Any other suggestions?
>
> -
> Shreyansh
Apologies for the modified subject in the previous email.
While sending out the patch, I didn't pay attention to the 'patch head
line'.
-
Shreyansh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] Hello Ferruh, Neil,
2017-02-21 13:42 ` [dpdk-dev] Hello Ferruh, Neil, Shreyansh Jain
2017-02-21 13:45 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Shreyansh Jain
@ 2017-02-21 14:39 ` Ferruh Yigit
2017-02-22 8:23 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Shreyansh Jain
2017-02-22 12:41 ` [dpdk-dev] Hello Ferruh, Neil, Neil Horman
2 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-02-21 14:39 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev, nhorman
On 2/21/2017 1:42 PM, Shreyansh Jain wrote:
> Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
> I create a draft patch for a single symbol change. (applies over v7
> of DPAA2 PMD)
>
> Can you tell me if this is the direction you were suggesting?
>
> I see two issues in this approach which are somewhat problematic for
> me to change all the symbols:
> 1) We saw a drop of over 5% when I replaced only 3 symbols (one
> of the most used ones, just for sampling). This also means that
> when more of such symbols are replaced, it would bring further
> drop. This was case when I used the Shared library approach.
> (*) I am not well versed with gcc symbol aliasing to comment for
> why such a drop would happen. But multiple test cycles confirm
> this.
> 2) I have to include a new header in almost all the source files for PMD/
> Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
> code. Essentially, any internal repo patch cannot be directly
> transposed to DPDK repo. Increased effort for each internal->
> external release
>
> Overall, I would like you to consider if this effort for changing names
> for exposed symbols is really useful or not.
As you showed below, this works for exporting proper APIs, but not sure
if this change worth or not.
>
> There is another approach - that of not using a drivers/common library.
> This again is problematic for us - NXP DPAA2 being a hardware, the lib
> and state for Crypto and Net hardware is tied together - so, having
> multiple instances of library breaks either of Crypto or Net PMD.
Isn't is possible to keep folder structure same, but produce single library.
Because these don't provide any API to the user application, perhaps not
need to be library at all.
Assuming that bus and pool won't be required without a driver existing,
is it possible have a single driver library that contains others?
For net driver, dependency is as following:
bus_fslmc --> common_dpaa2_qbman
pool_dpaa2 --> bus_fslmc, common_dpaa2_qbman
pmd_dpaa2 --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
So generating only "librte_pmd_dpaa2" which include above dependent ones.
For cryptodev pmd, I assume it has dependency to same modules:
pmd_crypto --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
And this will generate only crypto pmd library, including all again.
This will create duplication in binaries, but I think easier to manage
library dependencies.
And for above case, as far as I know, both net and crypto libraries can
be linked against a binary even there are duplicate symbols. Are you
getting error here?
>
> Any other suggestions?
>
> -
> Shreyansh
>
> --->8---
>
> From b9928ed44e69d7f9f9def0f06647a8d3bc25f284 Mon Sep 17 00:00:00 2001
> From: Shreyansh Jain <shreyansh.jain@nxp.com>
> Date: Fri, 10 Feb 2017 19:18:55 +0530
> Subject: [PATCH] dpaa2: fix for rte_* symbol naming
>
> This sample code:
> * creates nxp_compat.h containing custom version of MAP_STATIC_* and
> BIND_DEFAULT*
> Can't use the existing version because they are based on appending
> a string (_v[0-9]), not prepending as required in this case
> * creates nxp_shared_symbol.h for appending rte_* to symbols
> * declares functions
> * changes map file
>
> Hereafter:
> * for every newly introduced symbol, create NXP_*_SYMBOL mapping
> * put symbol in nxp_shared_symbols.h
> * add entry in map with rte_* prepended
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>
> ---
> drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 3 +
> .../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1 +
> drivers/common/dpaa2/qbman/include/nxp_compat.h | 70 ++++++++++++++++++++++
> .../dpaa2/qbman/include/nxp_shared_symbols.h | 41 +++++++++++++
> drivers/common/dpaa2/qbman/qbman_portal.c | 2 +
> .../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 2 +-
> 6 files changed, 118 insertions(+), 1 deletion(-)
> create mode 100644 drivers/common/dpaa2/qbman/include/nxp_compat.h
> create mode 100644 drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
>
> diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> index c80d6c5..1c157b9 100644
> --- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> +++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> @@ -59,9 +59,12 @@
>
> #include <fslmc_logs.h>
> #include <fslmc_vfio.h>
> +#include <fsl_qbman_portal.h>
> #include "dpaa2_hw_pvt.h"
> #include "dpaa2_hw_dpio.h"
>
> +#include <nxp_shared_symbols.h>
> +
> #define NUM_HOST_CPUS RTE_MAX_LCORE
>
> struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE];
> diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> index 7731772..63ffdd1 100644
> --- a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> +++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> @@ -29,6 +29,7 @@
> #define _FSL_QBMAN_PORTAL_H
>
> #include <fsl_qbman_base.h>
> +#include "nxp_compat.h"
>
> /**
> * DOC - QBMan portal APIs to implement the following functions:
> diff --git a/drivers/common/dpaa2/qbman/include/nxp_compat.h b/drivers/common/dpaa2/qbman/include/nxp_compat.h
> new file mode 100644
> index 0000000..edbbfde
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/include/nxp_compat.h
> @@ -0,0 +1,70 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright (C) 2016 NXP
> + *
> + * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_COMPAT_H_
> +#define _NXP_COMPAT_H_
> +#include <rte_common.h>
> +
> +#ifdef RTE_BUILD_SHARED_LIB
> +
> +/*
> + * BIND_DEFAULT_SYMBOL
> + * Creates a symbol version entry instructing the linker to bind references to
> + * symbol <b> to exported symbol <a>; it also appends the symbol version as
> + * per the map file.
> + */
> +#define NXP_SHARED_SYMBOL(b, a, n) __asm__(".symver " RTE_STR(b) ", " RTE_STR(a) "@@DPDK_" RTE_STR(n))
> +
> +/*
> + * MAP_STATIC_SYMBOL
> + * If a function has been bifurcated into multiple versions, none of which
> + * are defined as the exported symbol name in the map file, this macro can be
> + * used to alias a specific version of the symbol to its exported name. For
> + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
> + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
> + * building a shared library, this macro can be used to map either foo_v1 or
> + * foo_v2 to the symbol foo when building a static library, e.g.:
> + * MAP_STATIC_SYMBOL(void foo(), foo_v2);
> + */
> +#define NXP_STATIC_SYMBOL(f, p)
> +
> +#else
> +/*
> + * No symbol versioning in use
> + */
> +#define NXP_SHARED_SYMBOL(b, e, n)
> +#define NXP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p))))
> +/*
> + * RTE_BUILD_SHARED_LIB=n
> + */
> +#endif
> +
> +struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d);
> +
> +#endif /* _NXP_COMPAT_H_ */
> diff --git a/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
> new file mode 100644
> index 0000000..6faba36
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
> @@ -0,0 +1,41 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright (C) 2016 NXP
> + *
> + * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_SHARED_SYMBOLS_H_
> +#define _NXP_SHARED_SYMBOLS_H_
> +
> +#ifdef RTE_BUILD_SHARED_LIB
> +
> +#define qbman_swp_init rte_qbman_swp_init
> +
> +#endif
> +
> +#endif /* NXP_STATIC_SYMBOL */
> +
> +
> diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
> index 11116bd..f9bad4f 100644
> --- a/drivers/common/dpaa2/qbman/qbman_portal.c
> +++ b/drivers/common/dpaa2/qbman/qbman_portal.c
> @@ -178,6 +178,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
> portal_idx_map[p->desc.idx] = p;
> return p;
> }
> +NXP_SHARED_SYMBOL(qbman_swp_init, rte_qbman_swp_init, 17.02);
> +NXP_STATIC_SYMBOL(struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d), qbman_swp_init);
>
> void qbman_swp_finish(struct qbman_swp *p)
> {
> diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> index f653421..1dda776 100644
> --- a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> +++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> @@ -18,7 +18,7 @@ DPDK_17.02 {
> qbman_result_DQ_flags;
> qbman_result_has_new_result;
> qbman_swp_acquire;
> - qbman_swp_init;
> + rte_qbman_swp_init;
> qbman_swp_pull;
> qbman_swp_release;
> qbman_swp_send_multiple;
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-21 14:39 ` [dpdk-dev] Hello Ferruh, Neil, Ferruh Yigit
@ 2017-02-22 8:23 ` Shreyansh Jain
2017-02-24 9:58 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-22 8:23 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, nhorman, hemant.agrawal
(Modified the subject to: 'Re: [PATCHv7 03/47] common/dpaa2: adding
qbman driver' from 'Re: Hello Ferruh, Neil,')
Hello Ferruh,
On Tuesday 21 February 2017 08:09 PM, Ferruh Yigit wrote:
> On 2/21/2017 1:42 PM, Shreyansh Jain wrote:
>> Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
>> I create a draft patch for a single symbol change. (applies over v7
>> of DPAA2 PMD)
>>
>> Can you tell me if this is the direction you were suggesting?
>>
>> I see two issues in this approach which are somewhat problematic for
>> me to change all the symbols:
>> 1) We saw a drop of over 5% when I replaced only 3 symbols (one
>> of the most used ones, just for sampling). This also means that
>> when more of such symbols are replaced, it would bring further
>> drop. This was case when I used the Shared library approach.
>> (*) I am not well versed with gcc symbol aliasing to comment for
>> why such a drop would happen. But multiple test cycles confirm
>> this.
>> 2) I have to include a new header in almost all the source files for PMD/
>> Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
>> code. Essentially, any internal repo patch cannot be directly
>> transposed to DPDK repo. Increased effort for each internal->
>> external release
>>
>> Overall, I would like you to consider if this effort for changing names
>> for exposed symbols is really useful or not.
>
> As you showed below, this works for exporting proper APIs, but not sure
> if this change worth or not.
Given such symbol aliasing is an impact on performance, probably there
is a need to discuss the strictness of rte_* appending for driver
symbols.
As for cost of maintaining such code base, it can be rationalized over
a period of time, but not performance.
>
>>
>> There is another approach - that of not using a drivers/common library.
>> This again is problematic for us - NXP DPAA2 being a hardware, the lib
>> and state for Crypto and Net hardware is tied together - so, having
>> multiple instances of library breaks either of Crypto or Net PMD.
>
> Isn't is possible to keep folder structure same, but produce single library.
> Because these don't provide any API to the user application, perhaps not
> need to be library at all.
>
> Assuming that bus and pool won't be required without a driver existing,
> is it possible have a single driver library that contains others?
>
> For net driver, dependency is as following:
> bus_fslmc --> common_dpaa2_qbman
> pool_dpaa2 --> bus_fslmc, common_dpaa2_qbman
> pmd_dpaa2 --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
>
> So generating only "librte_pmd_dpaa2" which include above dependent ones.
>
> For cryptodev pmd, I assume it has dependency to same modules:
> pmd_crypto --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
>
> And this will generate only crypto pmd library, including all again.
>
>
> This will create duplication in binaries, but I think easier to manage
> library dependencies.
>
>
> And for above case, as far as I know, both net and crypto libraries can
> be linked against a binary even there are duplicate symbols. Are you
> getting error here?
>
<snip>
Thanks for your comments.
The key issue here is that driver/common is not actually a 'library' in
traditional sense. It is a driver support system. It provides
interfaces to interact with the hardware - and that includes the Net
and Crypto hardware.
Being a 'driver', this also has its own state. For example, a mem area
to interact with hardware queues, whether net or crypto - there is a
single instance of it.
This restricts its duplication as a library.
In fact, as of now the statefulness is quite limited, but once more
devices (like for eventdev) come into picture, this would become more
prominent.
Now, we have these possibility:
1. Have a shared library with non rte_* symbols
2. We have shared library with rte_* symbols
3. We have non-net devices (crypto, eventdev, ..) depend on net for
these hardware interfaces
(2) is hitting performance significantly.
(3) it not a clean solution, having driver/crypto depend on driver/net.
When new devices are there, more dependencies will occur.
In crux, probably we need to have a discussion on (1) and how strongly
we feel about that (specially in context of drivers).
-
Shreyansh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-22 8:23 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Shreyansh Jain
@ 2017-02-24 9:58 ` Ferruh Yigit
2017-02-27 10:01 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-02-24 9:58 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev, nhorman, hemant.agrawal
On 2/22/2017 8:23 AM, Shreyansh Jain wrote:
> (Modified the subject to: 'Re: [PATCHv7 03/47] common/dpaa2: adding
> qbman driver' from 'Re: Hello Ferruh, Neil,')
>
> Hello Ferruh,
>
> On Tuesday 21 February 2017 08:09 PM, Ferruh Yigit wrote:
>> On 2/21/2017 1:42 PM, Shreyansh Jain wrote:
>>> Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
>>> I create a draft patch for a single symbol change. (applies over v7
>>> of DPAA2 PMD)
>>>
>>> Can you tell me if this is the direction you were suggesting?
>>>
>>> I see two issues in this approach which are somewhat problematic for
>>> me to change all the symbols:
>>> 1) We saw a drop of over 5% when I replaced only 3 symbols (one
>>> of the most used ones, just for sampling). This also means that
>>> when more of such symbols are replaced, it would bring further
>>> drop. This was case when I used the Shared library approach.
>>> (*) I am not well versed with gcc symbol aliasing to comment for
>>> why such a drop would happen. But multiple test cycles confirm
>>> this.
>>> 2) I have to include a new header in almost all the source files for PMD/
>>> Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
>>> code. Essentially, any internal repo patch cannot be directly
>>> transposed to DPDK repo. Increased effort for each internal->
>>> external release
>>>
>>> Overall, I would like you to consider if this effort for changing names
>>> for exposed symbols is really useful or not.
>>
>> As you showed below, this works for exporting proper APIs, but not sure
>> if this change worth or not.
>
> Given such symbol aliasing is an impact on performance, probably there
> is a need to discuss the strictness of rte_* appending for driver
> symbols.
> As for cost of maintaining such code base, it can be rationalized over
> a period of time, but not performance.
>
>>
>>>
>>> There is another approach - that of not using a drivers/common library.
>>> This again is problematic for us - NXP DPAA2 being a hardware, the lib
>>> and state for Crypto and Net hardware is tied together - so, having
>>> multiple instances of library breaks either of Crypto or Net PMD.
>>
>> Isn't is possible to keep folder structure same, but produce single library.
>> Because these don't provide any API to the user application, perhaps not
>> need to be library at all.
>>
>> Assuming that bus and pool won't be required without a driver existing,
>> is it possible have a single driver library that contains others?
>>
>> For net driver, dependency is as following:
>> bus_fslmc --> common_dpaa2_qbman
>> pool_dpaa2 --> bus_fslmc, common_dpaa2_qbman
>> pmd_dpaa2 --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
>>
>> So generating only "librte_pmd_dpaa2" which include above dependent ones.
>>
>> For cryptodev pmd, I assume it has dependency to same modules:
>> pmd_crypto --> pool_dpaa2, bus_fslmc, common_dpaa2_qbman
>>
>> And this will generate only crypto pmd library, including all again.
>>
>>
>> This will create duplication in binaries, but I think easier to manage
>> library dependencies.
>>
>>
>> And for above case, as far as I know, both net and crypto libraries can
>> be linked against a binary even there are duplicate symbols. Are you
>> getting error here?
>>
> <snip>
>
> Thanks for your comments.
>
> The key issue here is that driver/common is not actually a 'library' in
> traditional sense. It is a driver support system. It provides
> interfaces to interact with the hardware - and that includes the Net
> and Crypto hardware.
>
> Being a 'driver', this also has its own state. For example, a mem area
> to interact with hardware queues, whether net or crypto - there is a
> single instance of it.
>
> This restricts its duplication as a library.
> In fact, as of now the statefulness is quite limited, but once more
> devices (like for eventdev) come into picture, this would become more
> prominent.
>
> Now, we have these possibility:
> 1. Have a shared library with non rte_* symbols
> 2. We have shared library with rte_* symbols
> 3. We have non-net devices (crypto, eventdev, ..) depend on net for
> these hardware interfaces
>
> (2) is hitting performance significantly.
> (3) it not a clean solution, having driver/crypto depend on driver/net.
> When new devices are there, more dependencies will occur.
>
> In crux, probably we need to have a discussion on (1) and how strongly
> we feel about that (specially in context of drivers).
Insight of above information, I would be OK with (1).
We can go with option (1) now, since these are not real APIs to user
application, it can be possible to change them if better solution found.
Do you think is it good idea to have different naming syntax for those
libraries to clarify they are for PMD internal usage?
>
> -
> Shreyansh
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-24 9:58 ` Ferruh Yigit
@ 2017-02-27 10:01 ` Shreyansh Jain
2017-02-27 15:35 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-27 10:01 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, nhorman, hemant.agrawal
Hello Ferruh,
On Friday 24 February 2017 03:28 PM, Ferruh Yigit wrote:
[snip]
>>
>> Now, we have these possibility:
>> 1. Have a shared library with non rte_* symbols
>> 2. We have shared library with rte_* symbols
>> 3. We have non-net devices (crypto, eventdev, ..) depend on net for
>> these hardware interfaces
>>
>> (2) is hitting performance significantly.
>> (3) it not a clean solution, having driver/crypto depend on driver/net.
>> When new devices are there, more dependencies will occur.
>>
>> In crux, probably we need to have a discussion on (1) and how strongly
>> we feel about that (specially in context of drivers).
>
> Insight of above information, I would be OK with (1).
Great. Thank you for understanding.
>
> We can go with option (1) now, since these are not real APIs to user
> application, it can be possible to change them if better solution found.
>
> Do you think is it good idea to have different naming syntax for those
> libraries to clarify they are for PMD internal usage?
>
Indeed. Current name is librte_common_dpaa2_*.
Do you think librte_drvlib_dpaa2 or librte_drvlib_dpaa2_pmd is better?
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-27 10:01 ` Shreyansh Jain
@ 2017-02-27 15:35 ` Ferruh Yigit
2017-02-28 5:27 ` Shreyansh Jain
0 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-02-27 15:35 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev, nhorman, hemant.agrawal
On 2/27/2017 10:01 AM, Shreyansh Jain wrote:
> Hello Ferruh,
>
> On Friday 24 February 2017 03:28 PM, Ferruh Yigit wrote:
>
> [snip]
>
>>>
>>> Now, we have these possibility:
>>> 1. Have a shared library with non rte_* symbols
>>> 2. We have shared library with rte_* symbols
>>> 3. We have non-net devices (crypto, eventdev, ..) depend on net for
>>> these hardware interfaces
>>>
>>> (2) is hitting performance significantly.
>>> (3) it not a clean solution, having driver/crypto depend on driver/net.
>>> When new devices are there, more dependencies will occur.
>>>
>>> In crux, probably we need to have a discussion on (1) and how strongly
>>> we feel about that (specially in context of drivers).
>>
>> Insight of above information, I would be OK with (1).
>
> Great. Thank you for understanding.
>
>>
>> We can go with option (1) now, since these are not real APIs to user
>> application, it can be possible to change them if better solution found.
>>
>> Do you think is it good idea to have different naming syntax for those
>> libraries to clarify they are for PMD internal usage?
>>
>
> Indeed. Current name is librte_common_dpaa2_*.
> Do you think librte_drvlib_dpaa2 or librte_drvlib_dpaa2_pmd is better?
common vs drvlib may not be different for who don't know about these
libraries, what about using "internal" or "private" kind of keyword?
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-27 15:35 ` Ferruh Yigit
@ 2017-02-28 5:27 ` Shreyansh Jain
2017-03-01 11:00 ` Thomas Monjalon
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-02-28 5:27 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, nhorman, Hemant Agrawal
> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Monday, February 27, 2017 9:06 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; nhorman@tuxdriver.com; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: Re: [PATCHv7 03/47] common/dpaa2: adding qbman driver
>
> On 2/27/2017 10:01 AM, Shreyansh Jain wrote:
> > Hello Ferruh,
> >
> > On Friday 24 February 2017 03:28 PM, Ferruh Yigit wrote:
> >
> > [snip]
> >
> >>>
> >>> Now, we have these possibility:
> >>> 1. Have a shared library with non rte_* symbols
> >>> 2. We have shared library with rte_* symbols
> >>> 3. We have non-net devices (crypto, eventdev, ..) depend on net for
> >>> these hardware interfaces
> >>>
> >>> (2) is hitting performance significantly.
> >>> (3) it not a clean solution, having driver/crypto depend on driver/net.
> >>> When new devices are there, more dependencies will occur.
> >>>
> >>> In crux, probably we need to have a discussion on (1) and how strongly
> >>> we feel about that (specially in context of drivers).
> >>
> >> Insight of above information, I would be OK with (1).
> >
> > Great. Thank you for understanding.
> >
> >>
> >> We can go with option (1) now, since these are not real APIs to user
> >> application, it can be possible to change them if better solution found.
> >>
> >> Do you think is it good idea to have different naming syntax for those
> >> libraries to clarify they are for PMD internal usage?
> >>
> >
> > Indeed. Current name is librte_common_dpaa2_*.
> > Do you think librte_drvlib_dpaa2 or librte_drvlib_dpaa2_pmd is better?
>
> common vs drvlib may not be different for who don't know about these
> libraries, what about using "internal" or "private" kind of keyword?
I am ok with librte_pvtlib_dpaa2_pmd or librte_pvtlib_dpaa2. Sounds fine?
('internal' is too long and its abbreviation 'int' doesn't make it easier
to read. :D )
-
Shreyansh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-02-28 5:27 ` Shreyansh Jain
@ 2017-03-01 11:00 ` Thomas Monjalon
2017-03-01 12:26 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Thomas Monjalon @ 2017-03-01 11:00 UTC (permalink / raw)
To: Shreyansh Jain, Hemant Agrawal; +Cc: dev, Ferruh Yigit, nhorman
2017-02-28 05:27, Shreyansh Jain:
> From: Ferruh Yigit
> > On 2/27/2017 10:01 AM, Shreyansh Jain wrote:
> > > On Friday 24 February 2017 03:28 PM, Ferruh Yigit wrote:
> > >> We can go with option (1) now, since these are not real APIs to user
> > >> application, it can be possible to change them if better solution found.
> > >>
> > >> Do you think is it good idea to have different naming syntax for those
> > >> libraries to clarify they are for PMD internal usage?
> > >>
> > >
> > > Indeed. Current name is librte_common_dpaa2_*.
> > > Do you think librte_drvlib_dpaa2 or librte_drvlib_dpaa2_pmd is better?
> >
> > common vs drvlib may not be different for who don't know about these
> > libraries, what about using "internal" or "private" kind of keyword?
>
> I am ok with librte_pvtlib_dpaa2_pmd or librte_pvtlib_dpaa2. Sounds fine?
> ('internal' is too long and its abbreviation 'int' doesn't make it easier
> to read. :D )
There is already "lib" in "librte". What about librte_internal_dpaa2_ prefix?
Internal is really the best word as you are requesting DPDK to host
libraries used only for your drivers.
I thought you agreed to host them outside of the DPDK repository.
What is your reason to keep pushing in DPDK?
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver
2017-03-01 11:00 ` Thomas Monjalon
@ 2017-03-01 12:26 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-01 12:26 UTC (permalink / raw)
To: Thomas Monjalon, Shreyansh Jain; +Cc: dev, Ferruh Yigit, nhorman
On 3/1/2017 4:30 PM, Thomas Monjalon wrote:
> 2017-02-28 05:27, Shreyansh Jain:
>> From: Ferruh Yigit
>>> On 2/27/2017 10:01 AM, Shreyansh Jain wrote:
>>>> On Friday 24 February 2017 03:28 PM, Ferruh Yigit wrote:
>>>>> We can go with option (1) now, since these are not real APIs to user
>>>>> application, it can be possible to change them if better solution found.
>>>>>
>>>>> Do you think is it good idea to have different naming syntax for those
>>>>> libraries to clarify they are for PMD internal usage?
>>>>>
>>>>
>>>> Indeed. Current name is librte_common_dpaa2_*.
>>>> Do you think librte_drvlib_dpaa2 or librte_drvlib_dpaa2_pmd is better?
>>>
>>> common vs drvlib may not be different for who don't know about these
>>> libraries, what about using "internal" or "private" kind of keyword?
>>
>> I am ok with librte_pvtlib_dpaa2_pmd or librte_pvtlib_dpaa2. Sounds fine?
>> ('internal' is too long and its abbreviation 'int' doesn't make it easier
>> to read. :D )
>
> There is already "lib" in "librte". What about librte_internal_dpaa2_ prefix?
>
Ok. We were just trying to avoid that long name. :)
> Internal is really the best word as you are requesting DPDK to host
> libraries used only for your drivers.
> I thought you agreed to host them outside of the DPDK repository.
> What is your reason to keep pushing in DPDK?
>
I don't think the last discussion closed like this. You suggested [1]
this as an option during handing of issue with rte.lib.mk causing the
parallel build dependency of shared lib to fail for drivers/common.
Ferruh has already fixed that[2].
The drivers/common is an integral part of PMD - very similar to a *base*
directory of any existing DPDK PMDs. The only difference is that *NXP's
base* is common across multiple drivers (bus, pool, net, crypto,
eventdev etc) - all of them interface with SoC using this 'driver
interface'. We named it as "driver common lib" - we could not find a
better way to name it. Probably, a hw driver interface or dpaa2_base is
a better explanation.
Imagine a PMD which resides within DPDK (dpaa2 pmd) which only has high
level interfaces with DPDK API and cannot talk to a real hardware (SoC)
because it lacks the basic driver interface. That would really not make
that code a 'PMD'.
Probably it would be better if we close what is the scope of a PMD
before this discussion is to go ahead. And, why would there be a need to
store this 'lib' externally.
Following is what Neil replied to your suggestion [3]. And we fully
agree with it.
"Please do not go with suggestion two, the more libraries get hosted
outside of the project, the less likely any sort of test/build/ongoing
maintenance from the community can be expected. If you're going to go
with solution (2), then you may as well host the entire PMD outside of
the DPDK project, and that more undesirable."
[1] http://dpdk.org/ml/archives/dev/2017-January/056243.html
[2] http://dpdk.org/ml/archives/dev/2017-January/056321.html
[3] http://dpdk.org/ml/archives/dev/2017-January/056292.html
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] Hello Ferruh, Neil,
2017-02-21 13:42 ` [dpdk-dev] Hello Ferruh, Neil, Shreyansh Jain
2017-02-21 13:45 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Shreyansh Jain
2017-02-21 14:39 ` [dpdk-dev] Hello Ferruh, Neil, Ferruh Yigit
@ 2017-02-22 12:41 ` Neil Horman
2 siblings, 0 replies; 549+ messages in thread
From: Neil Horman @ 2017-02-22 12:41 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: ferruh.yigit, dev
On Tue, Feb 21, 2017 at 07:12:58PM +0530, Shreyansh Jain wrote:
> Thanks for the suggestions about rte_* renaming in DPAA2 PMD.
> I create a draft patch for a single symbol change. (applies over v7
> of DPAA2 PMD)
>
> Can you tell me if this is the direction you were suggesting?
>
> I see two issues in this approach which are somewhat problematic for
> me to change all the symbols:
> 1) We saw a drop of over 5% when I replaced only 3 symbols (one
> of the most used ones, just for sampling). This also means that
> when more of such symbols are replaced, it would bring further
> drop. This was case when I used the Shared library approach.
> (*) I am not well versed with gcc symbol aliasing to comment for
> why such a drop would happen. But multiple test cycles confirm
> this.
> 2) I have to include a new header in almost all the source files for PMD/
> Pool/Bus etc. This is besides the STATIC_SYMBOL macros across the
> code. Essentially, any internal repo patch cannot be directly
> transposed to DPDK repo. Increased effort for each internal->
> external release
>
> Overall, I would like you to consider if this effort for changing names
> for exposed symbols is really useful or not.
>
> There is another approach - that of not using a drivers/common library.
> This again is problematic for us - NXP DPAA2 being a hardware, the lib
> and state for Crypto and Net hardware is tied together - so, having
> multiple instances of library breaks either of Crypto or Net PMD.
>
> Any other suggestions?
>
> -
> Shreyansh
>
> --->8---
>
> From b9928ed44e69d7f9f9def0f06647a8d3bc25f284 Mon Sep 17 00:00:00 2001
> From: Shreyansh Jain <shreyansh.jain@nxp.com>
> Date: Fri, 10 Feb 2017 19:18:55 +0530
> Subject: [PATCH] dpaa2: fix for rte_* symbol naming
>
> This sample code:
> * creates nxp_compat.h containing custom version of MAP_STATIC_* and
> BIND_DEFAULT*
> Can't use the existing version because they are based on appending
> a string (_v[0-9]), not prepending as required in this case
> * creates nxp_shared_symbol.h for appending rte_* to symbols
> * declares functions
> * changes map file
>
If thats what you are trying to do, I would suggest not using MAP_STATIC_SYMBOL,
as that will get confusing, maybe create a new macro called ALIAS or some such
in the compat header that already exists that just expands to an alias
attribute. Theres no point in redefining an existing macro if it doesn't
already do what you want.
> Hereafter:
> * for every newly introduced symbol, create NXP_*_SYMBOL mapping
> * put symbol in nxp_shared_symbols.h
> * add entry in map with rte_* prepended
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>
> ---
> drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 3 +
> .../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1 +
> drivers/common/dpaa2/qbman/include/nxp_compat.h | 70 ++++++++++++++++++++++
> .../dpaa2/qbman/include/nxp_shared_symbols.h | 41 +++++++++++++
> drivers/common/dpaa2/qbman/qbman_portal.c | 2 +
> .../dpaa2/qbman/rte_common_dpaa2_qbman_version.map | 2 +-
> 6 files changed, 118 insertions(+), 1 deletion(-)
> create mode 100644 drivers/common/dpaa2/qbman/include/nxp_compat.h
> create mode 100644 drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
>
> diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> index c80d6c5..1c157b9 100644
> --- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> +++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
> @@ -59,9 +59,12 @@
>
> #include <fslmc_logs.h>
> #include <fslmc_vfio.h>
> +#include <fsl_qbman_portal.h>
> #include "dpaa2_hw_pvt.h"
> #include "dpaa2_hw_dpio.h"
>
> +#include <nxp_shared_symbols.h>
> +
> #define NUM_HOST_CPUS RTE_MAX_LCORE
>
> struct dpaa2_io_portal_t dpaa2_io_portal[RTE_MAX_LCORE];
> diff --git a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> index 7731772..63ffdd1 100644
> --- a/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> +++ b/drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
> @@ -29,6 +29,7 @@
> #define _FSL_QBMAN_PORTAL_H
>
> #include <fsl_qbman_base.h>
> +#include "nxp_compat.h"
>
> /**
> * DOC - QBMan portal APIs to implement the following functions:
> diff --git a/drivers/common/dpaa2/qbman/include/nxp_compat.h b/drivers/common/dpaa2/qbman/include/nxp_compat.h
> new file mode 100644
> index 0000000..edbbfde
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/include/nxp_compat.h
> @@ -0,0 +1,70 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright (C) 2016 NXP
> + *
> + * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_COMPAT_H_
> +#define _NXP_COMPAT_H_
> +#include <rte_common.h>
> +
> +#ifdef RTE_BUILD_SHARED_LIB
> +
> +/*
> + * BIND_DEFAULT_SYMBOL
> + * Creates a symbol version entry instructing the linker to bind references to
> + * symbol <b> to exported symbol <a>; it also appends the symbol version as
> + * per the map file.
> + */
> +#define NXP_SHARED_SYMBOL(b, a, n) __asm__(".symver " RTE_STR(b) ", " RTE_STR(a) "@@DPDK_" RTE_STR(n))
> +
> +/*
> + * MAP_STATIC_SYMBOL
> + * If a function has been bifurcated into multiple versions, none of which
> + * are defined as the exported symbol name in the map file, this macro can be
> + * used to alias a specific version of the symbol to its exported name. For
> + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
> + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
> + * building a shared library, this macro can be used to map either foo_v1 or
> + * foo_v2 to the symbol foo when building a static library, e.g.:
> + * MAP_STATIC_SYMBOL(void foo(), foo_v2);
> + */
> +#define NXP_STATIC_SYMBOL(f, p)
> +
> +#else
> +/*
> + * No symbol versioning in use
> + */
> +#define NXP_SHARED_SYMBOL(b, e, n)
> +#define NXP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p))))
> +/*
> + * RTE_BUILD_SHARED_LIB=n
> + */
> +#endif
> +
> +struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d);
> +
> +#endif /* _NXP_COMPAT_H_ */
> diff --git a/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
> new file mode 100644
> index 0000000..6faba36
> --- /dev/null
> +++ b/drivers/common/dpaa2/qbman/include/nxp_shared_symbols.h
> @@ -0,0 +1,41 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright (C) 2016 NXP
> + *
> + * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _NXP_SHARED_SYMBOLS_H_
> +#define _NXP_SHARED_SYMBOLS_H_
> +
> +#ifdef RTE_BUILD_SHARED_LIB
> +
> +#define qbman_swp_init rte_qbman_swp_init
> +
> +#endif
> +
> +#endif /* NXP_STATIC_SYMBOL */
> +
> +
> diff --git a/drivers/common/dpaa2/qbman/qbman_portal.c b/drivers/common/dpaa2/qbman/qbman_portal.c
> index 11116bd..f9bad4f 100644
> --- a/drivers/common/dpaa2/qbman/qbman_portal.c
> +++ b/drivers/common/dpaa2/qbman/qbman_portal.c
> @@ -178,6 +178,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
> portal_idx_map[p->desc.idx] = p;
> return p;
> }
> +NXP_SHARED_SYMBOL(qbman_swp_init, rte_qbman_swp_init, 17.02);
> +NXP_STATIC_SYMBOL(struct qbman_swp *rte_qbman_swp_init(const struct qbman_swp_desc *d), qbman_swp_init);
>
> void qbman_swp_finish(struct qbman_swp *p)
> {
> diff --git a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> index f653421..1dda776 100644
> --- a/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> +++ b/drivers/common/dpaa2/qbman/rte_common_dpaa2_qbman_version.map
> @@ -18,7 +18,7 @@ DPDK_17.02 {
> qbman_result_DQ_flags;
> qbman_result_has_new_result;
> qbman_swp_acquire;
> - qbman_swp_init;
> + rte_qbman_swp_init;
> qbman_swp_pull;
> qbman_swp_release;
> qbman_swp_send_multiple;
> --
> 2.7.4
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 04/47] bus/fslmc: introducing fsl-mc bus driver
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (2 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 03/47] common/dpaa2: adding qbman driver Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 05/47] bus/fslmc: introduce MC object functions Hemant Agrawal
` (44 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
for NXP DPAA2 SoCs.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +-
drivers/Makefile | 1 +
drivers/bus/Makefile | 36 +++++++
drivers/bus/fslmc/Makefile | 52 ++++++++++
drivers/bus/fslmc/fslmc_bus.c | 125 +++++++++++++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 7 ++
drivers/bus/fslmc/rte_fslmc.h | 148 ++++++++++++++++++++++++++++
drivers/common/Makefile | 4 +
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
12 files changed, 394 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ec5683..c151546 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -358,6 +358,7 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
QLogic bnx2x
diff --git a/config/common_base b/config/common_base
index 71a4fcb..d162228 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,6 +287,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=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 66df54c..365ae5a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -40,3 +41,8 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
#
CONFIG_RTE_MAX_LCORE=8
CONFIG_RTE_MAX_NUMA_NODES=1
+
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=y
diff --git a/drivers/Makefile b/drivers/Makefile
index d5580f6..bdae63b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -32,6 +32,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
+DIRS-y += bus
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000..60e9764
--- /dev/null
+++ b/drivers/bus/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_FSLMC_BUS) += fslmc
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
new file mode 100644
index 0000000..5a0fd61
--- /dev/null
+++ b/drivers/bus/fslmc/Makefile
@@ -0,0 +1,52 @@
+# 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_fslmc.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_fslmc_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
new file mode 100644
index 0000000..8a4f519
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -0,0 +1,125 @@
+/*-
+ * 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.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_ethdev.h>
+
+#include "rte_fslmc.h"
+
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+ RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+struct rte_fslmc_bus rte_fslmc_bus;
+
+static int
+rte_fslmc_scan(void)
+{
+ return 0;
+}
+
+static int
+rte_fslmc_match(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
+ return 0;
+
+ return 1;
+}
+
+static int
+rte_fslmc_probe(void)
+{
+ int ret = -1;
+ struct rte_dpaa2_device *dev;
+ struct rte_dpaa2_driver *drv;
+
+ TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
+ TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
+ ret = rte_fslmc_match(drv, dev);
+ if (ret)
+ continue;
+
+ if (!drv->probe)
+ continue;
+
+ ret = drv->probe(drv, dev);
+ if (ret)
+ FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
+ break;
+ }
+ }
+ return ret;
+}
+
+/*register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
+{
+ RTE_VERIFY(driver);
+
+ TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = &rte_fslmc_bus;
+}
+
+/*un-register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver)
+{
+ struct rte_fslmc_bus *fslmc_bus;
+
+ fslmc_bus = driver->fslmc_bus;
+
+ TAILQ_REMOVE(&fslmc_bus->driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = NULL;
+}
+
+struct rte_fslmc_bus rte_fslmc_bus = {
+ .bus = {
+ .scan = rte_fslmc_scan,
+ .probe = rte_fslmc_probe,
+ },
+ .device_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.device_list),
+ .driver_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus);
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
new file mode 100644
index 0000000..4d525ba
--- /dev/null
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -0,0 +1,7 @@
+DPDK_17.02 {
+ global:
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
new file mode 100644
index 0000000..040ab95
--- /dev/null
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -0,0 +1,148 @@
+/*-
+ * 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 _RTE_FSLMC_H_
+#define _RTE_FSLMC_H_
+
+/**
+ * @file
+ *
+ * RTE FSLMC Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/** Name of FSLMC Bus */
+#define FSLMC_BUS_NAME "FSLMC"
+
+struct rte_dpaa2_driver;
+
+/* DPAA2 Device and Driver lists for FSLMC bus */
+TAILQ_HEAD(rte_fslmc_device_list, rte_dpaa2_device);
+TAILQ_HEAD(rte_fslmc_driver_list, rte_dpaa2_driver);
+
+extern struct rte_fslmc_bus rte_fslmc_bus;
+
+/**
+ * A structure describing a DPAA2 device.
+ */
+struct rte_dpaa2_device {
+ TAILQ_ENTRY(rte_dpaa2_device) next; /**< Next probed DPAA2 device. */
+ struct rte_device device; /**< Inherit core device */
+ union {
+ struct rte_eth_dev *eth_dev; /**< ethernet device */
+ struct rte_cryptodev *cryptodev; /**< Crypto Device */
+ };
+ uint16_t dev_type; /**< Device Type */
+ uint16_t object_id; /**< DPAA2 Object ID */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
+ struct rte_dpaa2_driver *driver; /**< Associated driver */
+};
+
+typedef int (*rte_dpaa2_probe_t)(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev);
+typedef int (*rte_dpaa2_remove_t)(struct rte_dpaa2_device *dpaa2_dev);
+
+/**
+ * A structure describing a DPAA2 driver.
+ */
+struct rte_dpaa2_driver {
+ TAILQ_ENTRY(rte_dpaa2_driver) next; /**< Next in list. */
+ struct rte_driver driver; /**< Inherit core driver. */
+ struct rte_fslmc_bus *fslmc_bus; /**< FSLMC bus reference */
+ uint32_t drv_flags; /**< Flags for controlling device.*/
+ uint16_t drv_type; /**< Driver Type */
+ rte_dpaa2_probe_t probe;
+ rte_dpaa2_remove_t remove;
+};
+
+/*
+ * FSLMC bus
+ */
+struct rte_fslmc_bus {
+ struct rte_bus bus; /**< Generic Bus object */
+ struct rte_fslmc_device_list device_list;
+ /**< FSLMC DPAA2 Device list */
+ struct rte_fslmc_driver_list driver_list;
+ /**< FSLMC DPAA2 Driver list */
+ int device_count;
+ /**< Optional: Count of devices on bus */
+};
+
+/**
+ * Register a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be registered.
+ */
+void rte_fslmc_driver_register(struct rte_dpaa2_driver *driver);
+
+/**
+ * Unregister a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be unregistered.
+ */
+void rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver);
+
+/** Helper for DPAA2 device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_DPAA2(nm, dpaa2_drv) \
+RTE_INIT(dpaa2initfn_ ##nm); \
+static void dpaa2initfn_ ##nm(void) \
+{\
+ (dpaa2_drv).driver.name = RTE_STR(nm);\
+ rte_fslmc_driver_register(&dpaa2_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_FSLMC_H_ */
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index e5bfecb..cba1134 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),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..9681729 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
+endif
+
DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_COMMON) += qbman
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 5e64d23..7ac1ba7 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -36,6 +36,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_common_dpaa2_qbman.a
+ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
+endif
+
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 05/47] bus/fslmc: introduce MC object functions
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (3 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 04/47] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 06/47] bus/fslmc: add mc dpni object support Hemant Agrawal
` (43 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch intoduces the DPAA2 MC(Management complex Driver).
This is a minimal set of low level functions to send and
receive commands to the fsl-mc. It includes support for basic
management commands and commands to manipulate MC objects.
This is common to be used by various DPAA2 PMDs. e.g.net, crypto
and other drivers.
This is a low level library also used in kernel.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 7 ++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++++++++++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 +++++++++++++++++
drivers/bus/fslmc/mc/mc_sys.c | 114 ++++++++++++++++++
4 files changed, 464 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 5a0fd61..1058f0f 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -37,6 +37,10 @@ LIB = librte_bus_fslmc.a
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += "-Wno-strict-aliasing"
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
# versioning export map
EXPORT_MAP := rte_bus_fslmc_version.map
@@ -44,6 +48,9 @@ EXPORT_MAP := rte_bus_fslmc_version.map
# library version
LIBABIVER := 1
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/mc_sys.c
+
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
new file mode 100644
index 0000000..bc41646
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
@@ -0,0 +1,238 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#define MC_CMD_NUM_OF_PARAMS 7
+
+#define MAKE_UMASK64(_width) \
+ ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : \
+ (uint64_t)-1))
+
+static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val)
+{
+ return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+
+static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width)
+{
+ return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+struct mc_command {
+ uint64_t header;
+ uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+/**
+ * enum mc_cmd_status - indicates MC status at command response
+ * @MC_CMD_STATUS_OK: Completed successfully
+ * @MC_CMD_STATUS_READY: Ready to be processed
+ * @MC_CMD_STATUS_AUTH_ERR: Authentication error
+ * @MC_CMD_STATUS_NO_PRIVILEGE: No privilege
+ * @MC_CMD_STATUS_DMA_ERR: DMA or I/O error
+ * @MC_CMD_STATUS_CONFIG_ERR: Configuration error
+ * @MC_CMD_STATUS_TIMEOUT: Operation timed out
+ * @MC_CMD_STATUS_NO_RESOURCE: No resources
+ * @MC_CMD_STATUS_NO_MEMORY: No memory available
+ * @MC_CMD_STATUS_BUSY: Device is busy
+ * @MC_CMD_STATUS_UNSUPPORTED_OP: Unsupported operation
+ * @MC_CMD_STATUS_INVALID_STATE: Invalid state
+ */
+enum mc_cmd_status {
+ MC_CMD_STATUS_OK = 0x0,
+ MC_CMD_STATUS_READY = 0x1,
+ MC_CMD_STATUS_AUTH_ERR = 0x3,
+ MC_CMD_STATUS_NO_PRIVILEGE = 0x4,
+ MC_CMD_STATUS_DMA_ERR = 0x5,
+ MC_CMD_STATUS_CONFIG_ERR = 0x6,
+ MC_CMD_STATUS_TIMEOUT = 0x7,
+ MC_CMD_STATUS_NO_RESOURCE = 0x8,
+ MC_CMD_STATUS_NO_MEMORY = 0x9,
+ MC_CMD_STATUS_BUSY = 0xA,
+ MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,
+ MC_CMD_STATUS_INVALID_STATE = 0xC
+};
+
+/* MC command flags */
+
+/**
+ * High priority flag
+ */
+#define MC_CMD_FLAG_PRI 0x00008000
+/**
+ * Command completion flag
+ */
+#define MC_CMD_FLAG_INTR_DIS 0x01000000
+
+/**
+ * Command ID field offset
+ */
+#define MC_CMD_HDR_CMDID_O 48
+/**
+ * Command ID field size
+ */
+#define MC_CMD_HDR_CMDID_S 16
+/**
+ * Token field offset
+ */
+#define MC_CMD_HDR_TOKEN_O 32
+/**
+ * Token field size
+ */
+#define MC_CMD_HDR_TOKEN_S 16
+/**
+ * Status field offset
+ */
+#define MC_CMD_HDR_STATUS_O 16
+/**
+ * Status field size
+ */
+#define MC_CMD_HDR_STATUS_S 8
+/**
+ * Flags field offset
+ */
+#define MC_CMD_HDR_FLAGS_O 0
+/**
+ * Flags field size
+ */
+#define MC_CMD_HDR_FLAGS_S 32
+/**
+ * Command flags mask
+ */
+#define MC_CMD_HDR_FLAGS_MASK 0xFF00FF00
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+ ((enum mc_cmd_status)mc_dec((_hdr), \
+ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
+
+#define MC_PREP_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= cpu_to_le64(mc_enc((_offset), (_width), _arg)))
+
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(cpu_to_le64(_ext[_param]), (_offset), (_width)))
+
+#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg))
+
+#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width)))
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ uint64_t hdr;
+
+ hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+ hdr |= mc_enc(MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S,
+ (cmd_flags & MC_CMD_HDR_FLAGS_MASK));
+ hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
+ hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+ MC_CMD_STATUS_READY);
+
+ return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+ struct mc_command *cmd)
+{
+ int i;
+ uint32_t word;
+
+ /* copy command parameters into the portal */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ iowrite64(cmd->params[i], &portal->params[i]);
+
+ /* submit the command by writing the header */
+ word = (uint32_t)mc_dec(cmd->header, 32, 32);
+ iowrite32(word, (((uint32_t *)&portal->header) + 1));
+
+ word = (uint32_t)mc_dec(cmd->header, 0, 32);
+ iowrite32(word, (uint32_t *)&portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(
+ struct mc_command __iomem *portal,
+ struct mc_command *resp)
+{
+ int i;
+ enum mc_cmd_status status;
+
+ /* Copy command response header from MC portal: */
+ resp->header = ioread64(&portal->header);
+ status = MC_CMD_HDR_READ_STATUS(resp->header);
+ if (status != MC_CMD_STATUS_OK)
+ return status;
+
+ /* Copy command response data from MC portal: */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ resp->params[i] = ioread64(&portal->params[i]);
+
+ return status;
+}
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_mc_sys.h b/drivers/bus/fslmc/mc/fsl_mc_sys.h
new file mode 100644
index 0000000..ebada60
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_sys.h
@@ -0,0 +1,105 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#ifdef __linux_driver__
+
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/slab.h>
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+
+#else /* __linux_driver__ */
+
+#include <stdio.h>
+#include <libio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <linux/byteorder/little_endian.h>
+
+#define cpu_to_le64(x) __cpu_to_le64(x)
+#ifndef dmb
+#define dmb() {__asm__ __volatile__("" : : : "memory"); }
+#endif
+#define __iormb() dmb()
+#define __iowmb() dmb()
+#define __arch_getq(a) (*(volatile unsigned long *)(a))
+#define __arch_putq(v, a) (*(volatile unsigned long *)(a) = (v))
+#define __arch_putq32(v, a) (*(volatile unsigned int *)(a) = (v))
+#define readq(c) \
+ ({ uint64_t __v = __arch_getq(c); __iormb(); __v; })
+#define writeq(v, c) \
+ ({ uint64_t __v = v; __iowmb(); __arch_putq(__v, c); __v; })
+#define writeq32(v, c) \
+ ({ uint32_t __v = v; __iowmb(); __arch_putq32(__v, c); __v; })
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+#define iowrite32(_v, _p) writeq32(_v, _p)
+#define __iomem
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+/*GPP is supposed to use MC commands with low priority*/
+#define CMD_PRI_LOW 0 /*!< Low Priority command indication */
+
+struct mc_command;
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* __linux_driver__ */
+
+#endif /* _FSL_MC_SYS_H */
diff --git a/drivers/bus/fslmc/mc/mc_sys.c b/drivers/bus/fslmc/mc/mc_sys.c
new file mode 100644
index 0000000..4573165
--- /dev/null
+++ b/drivers/bus/fslmc/mc/mc_sys.c
@@ -0,0 +1,114 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+
+#include <rte_spinlock.h>
+
+/** User space framework uses MC Portal in shared mode. Following change
+ * introduces lock in MC FLIB
+ */
+
+/**
+ * A static spinlock initializer.
+ */
+static rte_spinlock_t mc_portal_lock = RTE_SPINLOCK_INITIALIZER;
+
+static int mc_status_to_error(enum mc_cmd_status status)
+{
+ switch (status) {
+ case MC_CMD_STATUS_OK:
+ return 0;
+ case MC_CMD_STATUS_AUTH_ERR:
+ return -EACCES; /* Token error */
+ case MC_CMD_STATUS_NO_PRIVILEGE:
+ return -EPERM; /* Permission denied */
+ case MC_CMD_STATUS_DMA_ERR:
+ return -EIO; /* Input/Output error */
+ case MC_CMD_STATUS_CONFIG_ERR:
+ return -EINVAL; /* Device not configured */
+ case MC_CMD_STATUS_TIMEOUT:
+ return -ETIMEDOUT; /* Operation timed out */
+ case MC_CMD_STATUS_NO_RESOURCE:
+ return -ENAVAIL; /* Resource temporarily unavailable */
+ case MC_CMD_STATUS_NO_MEMORY:
+ return -ENOMEM; /* Cannot allocate memory */
+ case MC_CMD_STATUS_BUSY:
+ return -EBUSY; /* Device busy */
+ case MC_CMD_STATUS_UNSUPPORTED_OP:
+ return -ENOTSUP; /* Operation not supported by device */
+ case MC_CMD_STATUS_INVALID_STATE:
+ return -ENODEV; /* Invalid device state */
+ default:
+ break;
+ }
+
+ /* Not expected to reach here */
+ return -EINVAL;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+ enum mc_cmd_status status;
+
+ if (!mc_io || !mc_io->regs)
+ return -EACCES;
+
+ /* --- Call lock function here in case portal is shared --- */
+ rte_spinlock_lock(&mc_portal_lock);
+
+ mc_write_command(mc_io->regs, cmd);
+
+ /* Spin until status changes */
+ do {
+ status = MC_CMD_HDR_READ_STATUS(ioread64(mc_io->regs));
+
+ /* --- Call wait function here to prevent blocking ---
+ * Change the loop condition accordingly to exit on timeout.
+ */
+ } while (status == MC_CMD_STATUS_READY);
+
+ /* Read the response back into the command buffer */
+ mc_read_response(mc_io->regs, cmd);
+
+ /* --- Call unlock function here in case portal is shared --- */
+ rte_spinlock_unlock(&mc_portal_lock);
+
+ return mc_status_to_error(status);
+}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 06/47] bus/fslmc: add mc dpni object support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (4 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 05/47] bus/fslmc: introduce MC object functions Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 07/47] bus/fslmc: add mc dpio " Hemant Agrawal
` (42 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC
driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpni.c | 739 ++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpkg.h | 184 ++++
drivers/bus/fslmc/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 334 ++++++++
drivers/bus/fslmc/mc/fsl_net.h | 487 +++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 22 +
7 files changed, 2984 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 1058f0f..15ab89a 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -49,6 +49,7 @@ EXPORT_MAP := rte_bus_fslmc_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/dpni.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpni.c b/drivers/bus/fslmc/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpkg.h b/drivers/bus/fslmc/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni.h b/drivers/bus/fslmc/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpni_cmd.h b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_net.h b/drivers/bus/fslmc/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4d525ba..d49dda8 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,5 +1,27 @@
DPDK_17.02 {
global:
+ dpni_close;
+ dpni_disable;
+ dpni_enable;
+ dpni_get_attributes;
+ dpni_get_link_state;
+ dpni_get_primary_mac_addr;
+ dpni_get_qdid;
+ dpni_get_queue;
+ dpni_get_statistics;
+ dpni_open;
+ dpni_prepare_key_cfg;
+ dpni_reset;
+ dpni_reset_statistics;
+ dpni_set_buffer_layout;
+ dpni_set_errors_behavior;
+ dpni_set_max_frame_length;
+ dpni_set_offload;
+ dpni_set_pools;
+ dpni_set_queue;
+ dpni_set_rx_tc_dist;
+ dpni_set_tx_confirmation_mode;
+ dpni_set_unicast_promisc;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 07/47] bus/fslmc: add mc dpio object support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (5 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 06/47] bus/fslmc: add mc dpni object support Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 08/47] bus/fslmc: add mc dpbp " Hemant Agrawal
` (41 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the DPIO object support in MC driver.
DPIO - Data Path Input Output represent the processing
context to access the QBMAN HW for packet I/O.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpio.c | 279 +++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 8 +
5 files changed, 691 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 15ab89a..53ab17b 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpio.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpio.c b/drivers/bus/fslmc/mc/dpio.c
new file mode 100644
index 0000000..7f7359d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpio.c
@@ -0,0 +1,279 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpio.h>
+#include <fsl_dpio_cmd.h>
+
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPIO_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
+ cmd_flags,
+ token);
+ DPIO_CMD_SET_STASHING_DEST(cmd, sdest);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_STASHING_DEST,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_STASHING_DEST(cmd, *sdest);
+
+ return 0;
+}
+
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPIO_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpio.h b/drivers/bus/fslmc/mc/fsl_dpio.h
new file mode 100644
index 0000000..6d86f07
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio.h
@@ -0,0 +1,282 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPIO_H
+#define __FSL_DPIO_H
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and any MC portals
+ * assigned to the parent container; this token must be used in
+ * all subsequent commands for this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token);
+
+/**
+ * dpio_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * struct dpio_cfg - Structure representing DPIO configuration
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_cfg {
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_create() - Create the DPIO object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPIO object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpio_destroy() - Destroy the DPIO object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_is_enabled() - Check if the DPIO is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_set_stashing_destination() - Set the stashing destination.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest);
+
+/**
+ * dpio_get_stashing_destination() - Get the stashing destination..
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: Returns the stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ * @qbman_version: QBMAN version
+ */
+struct dpio_attr {
+ int id;
+ uint64_t qbman_portal_ce_offset;
+ uint64_t qbman_portal_ci_offset;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+ uint32_t qbman_version;
+ uint32_t clk;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+/**
+ * dpio_get_api_version() - Get Data Path I/O API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path i/o API
+ * @minor_ver: Minor version of data path i/o API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPIO_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpio_cmd.h b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
new file mode 100644
index 0000000..c4b613e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
@@ -0,0 +1,121 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPIO_CMD_H
+#define _FSL_DPIO_CMD_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 4
+#define DPIO_VER_MINOR 2
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPIO_CMDID_OPEN ((0x803 << 4) | (0x1))
+#define DPIO_CMDID_CREATE ((0x903 << 4) | (0x1))
+#define DPIO_CMDID_DESTROY ((0x983 << 4) | (0x1))
+#define DPIO_CMDID_GET_API_VERSION ((0xa03 << 4) | (0x1))
+
+#define DPIO_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPIO_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPIO_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPIO_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPIO_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPIO_CMDID_SET_STASHING_DEST ((0x120 << 4) | (0x1))
+#define DPIO_CMDID_GET_STASHING_DEST ((0x121 << 4) | (0x1))
+#define DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL ((0x122 << 4) | (0x1))
+#define DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL ((0x123 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 2, enum dpio_channel_mode, \
+ cfg->channel_mode);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->num_priorities);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
+ MC_RSP_OP(cmd, 3, 0, 32, uint32_t, attr->qbman_version);\
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, attr->clk);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_SET_STASHING_DEST(cmd, sdest) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_STASHING_DEST(cmd, sdest) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, channel_index) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, channel_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index d49dda8..daf6b8f 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,5 +1,13 @@
DPDK_17.02 {
global:
+
+ dpio_close;
+ dpio_disable;
+ dpio_enable;
+ dpio_get_attributes;
+ dpio_open;
+ dpio_reset;
+ dpio_set_stashing_destination;
dpni_close;
dpni_disable;
dpni_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 08/47] bus/fslmc: add mc dpbp object support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (6 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 07/47] bus/fslmc: add mc dpio " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 09/47] bus/fslmc: add mc dpseci " Hemant Agrawal
` (40 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
DPBP object represent a hw based buffer pool instance
in the DPAA2 hardware.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpbp.c | 237 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 ++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 5 +
5 files changed, 553 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 53ab17b..628e517 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpbp.c b/drivers/bus/fslmc/mc/dpbp.c
new file mode 100644
index 0000000..0d93e0c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpbp.c
@@ -0,0 +1,237 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpbp.h>
+#include <fsl_dpbp_cmd.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ (void)(cfg); /* unused */
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPBP_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp.h b/drivers/bus/fslmc/mc/fsl_dpbp.h
new file mode 100644
index 0000000..65262bd
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp.h
@@ -0,0 +1,227 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpbp_id: DPBP unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpbp_create function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_cfg - Structure representing DPBP configuration
+ * @options: place holder
+ */
+struct dpbp_cfg {
+ uint32_t options;
+};
+
+/**
+ * dpbp_create() - Create the DPBP object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPBP object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpbp_destroy() - Destroy the DPBP object and release all its resources.
+ * @dprc_token: Parent container token; '0' for default container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_is_enabled() - Check if the DPBP is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ uint16_t bpid;
+};
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/**
+ * dpbp_get_api_version() - Get buffer pool API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path buffer pool API
+ * @minor_ver: Minor version of data path buffer pool API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPBP_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
new file mode 100644
index 0000000..a6bfabe
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
@@ -0,0 +1,83 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPBP_CMD_H
+#define _FSL_DPBP_CMD_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 3
+#define DPBP_VER_MINOR 2
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPBP_CMDID_OPEN ((0x804 << 4) | (0x1))
+#define DPBP_CMDID_CREATE ((0x904 << 4) | (0x1))
+#define DPBP_CMDID_DESTROY ((0x984 << 4) | (0x1))
+#define DPBP_CMDID_GET_API_VERSION ((0xa04 << 4) | (0x1))
+
+#define DPBP_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPBP_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPBP_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPBP_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPBP_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPBP_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index daf6b8f..5167262 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,11 @@
DPDK_17.02 {
global:
+ dpbp_disable;
+ dpbp_enable;
+ dpbp_get_attributes;
+ dpbp_open;
+ dpbp_reset;
dpio_close;
dpio_disable;
dpio_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 09/47] bus/fslmc: add mc dpseci object support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (7 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 08/47] bus/fslmc: add mc dpbp " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 10/47] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
` (39 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
dpseci represent a instance of SEC HW in DPAA2.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpseci.c | 534 ++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 668 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 255 +++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 10 +
5 files changed, 1468 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 628e517..4a118a3 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpni.c \
+ mc/dpseci.c \
mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpseci.c b/drivers/bus/fslmc/mc/dpseci.c
new file mode 100644
index 0000000..bc8c9c5
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpseci.c
@@ -0,0 +1,534 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpseci.h>
+#include <fsl_dpseci_cmd.h>
+
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPSECI_CMD_OPEN(cmd, dpseci_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPSECI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_IS_ENABLED,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ(cmd, *type, irq_cfg);
+
+ return 0;
+}
+
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_ENABLE(cmd, *en);
+
+ return 0;
+}
+
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_ENABLE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_MASK(cmd, *mask);
+
+ return 0;
+}
+
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_MASK,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_IRQ_STATUS(cmd, *status);
+
+ return 0;
+}
+
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLEAR_IRQ_STATUS,
+ cmd_flags,
+ token);
+ DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_RX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_RX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_RX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_TX_QUEUE,
+ cmd_flags,
+ token);
+ DPSECI_CMD_GET_TX_QUEUE(cmd, queue);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_TX_QUEUE(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_COUNTERS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters);
+
+ return 0;
+}
+
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPSECI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci.h b/drivers/bus/fslmc/mc/fsl_dpseci.h
new file mode 100644
index 0000000..b8c6dcc
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci.h
@@ -0,0 +1,668 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPSECI_H
+#define __FSL_DPSECI_H
+
+/* Data Path SEC Interface API
+ * Contains initialization APIs and runtime control APIs for DPSECI
+ */
+
+struct fsl_mc_io;
+
+/**
+ * General DPSECI macros
+ */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPSECI object
+ */
+#define DPSECI_PRIO_NUM 8
+
+/**
+ * All queues considered; see dpseci_set_rx_queue()
+ */
+#define DPSECI_ALL_QUEUES (uint8_t)(-1)
+
+/**
+ * dpseci_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpseci_id: DPSECI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpseci_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpseci_id,
+ uint16_t *token);
+
+/**
+ * dpseci_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_cfg - Structure representing DPSECI configuration
+ * @num_tx_queues: num of queues towards the SEC
+ * @num_rx_queues: num of queues back from the SEC
+ * @priorities: Priorities for the SEC hardware processing;
+ * each place in the array is the priority of the tx queue
+ * towards the SEC,
+ * valid priorities are configured with values 1-8;
+ */
+struct dpseci_cfg {
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+ uint8_t priorities[DPSECI_PRIO_NUM];
+};
+
+/**
+ * dpseci_create() - Create the DPSECI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPSECI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpseci_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpseci_destroy() - Destroy the DPSECI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpseci_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpseci_enable() - Enable the DPSECI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_disable() - Disable the DPSECI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpseci_is_enabled() - Check if the DPSECI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpseci_reset() - Reset the DPSECI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpseci_irq_cfg - IRQ configuration
+ * @addr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+ * @irq_num: A user defined number associated with this IRQ
+ */
+struct dpseci_irq_cfg {
+ uint64_t addr;
+ uint32_t val;
+ int irq_num;
+};
+
+/**
+ * dpseci_set_irq() - Set IRQ information for the DPSECI to trigger an interrupt
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: Identifies the interrupt index to configure
+ * @irq_cfg: IRQ configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_get_irq() - Get IRQ information from the DPSECI
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @type: Interrupt type: 0 represents message interrupt
+ * type (both irq_addr and irq_val are valid)
+ * @irq_cfg: IRQ attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ int *type,
+ struct dpseci_irq_cfg *irq_cfg);
+
+/**
+ * dpseci_set_irq_enable() - Set overall interrupt state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Interrupt state - enable = 1, disable = 0
+ *
+ * Allows GPP software to control when interrupts are generated.
+ * Each interrupt can have up to 32 causes. The enable/disable control's the
+ * overall interrupt state. if the interrupt is disabled no causes will cause
+ * an interrupt
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t en);
+
+/**
+ * dpseci_get_irq_enable() - Get overall interrupt state
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @en: Returned Interrupt state - enable = 1, disable = 0
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint8_t *en);
+
+/**
+ * dpseci_set_irq_mask() - Set interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: event mask to trigger interrupt;
+ * each bit:
+ * 0 = ignore event
+ * 1 = consider event for asserting IRQ
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t mask);
+
+/**
+ * dpseci_get_irq_mask() - Get interrupt mask.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @mask: Returned event mask to trigger interrupt
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *mask);
+
+/**
+ * dpseci_get_irq_status() - Get the current status of any pending interrupts
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: Returned interrupts status - one bit per cause:
+ * 0 = no interrupt pending
+ * 1 = interrupt pending
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t *status);
+
+/**
+ * dpseci_clear_irq_status() - Clear a pending interrupt's status
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @irq_index: The interrupt index to configure
+ * @status: bits to clear (W1C) - one bit per cause:
+ * 0 = don't change
+ * 1 = clear status bit
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t irq_index,
+ uint32_t status);
+
+/**
+ * struct dpseci_attr - Structure representing DPSECI attributes
+ * @id: DPSECI object ID
+ * @num_tx_queues: number of queues towards the SEC
+ * @num_rx_queues: number of queues back from the SEC
+ */
+struct dpseci_attr {
+ int id;
+ uint8_t num_tx_queues;
+ uint8_t num_rx_queues;
+};
+
+/**
+ * dpseci_get_attributes() - Retrieve DPSECI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_attr *attr);
+
+/**
+ * enum dpseci_dest - DPSECI destination types
+ * @DPSECI_DEST_NONE: Unassigned destination; The queue is set in parked mode
+ * and does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPSECI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPSECI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpseci_dest {
+ DPSECI_DEST_NONE = 0,
+ DPSECI_DEST_DPIO = 1,
+ DPSECI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpseci_dest_cfg - Structure representing DPSECI destination parameters
+ * @dest_type: Destination type
+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
+ * are 0-1 or 0-7, depending on the number of priorities in that
+ * channel; not relevant for 'DPSECI_DEST_NONE' option
+ */
+struct dpseci_dest_cfg {
+ enum dpseci_dest dest_type;
+ int dest_id;
+ uint8_t priority;
+};
+
+/**
+ * DPSECI queue modification options
+ */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPSECI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPSECI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Select to modify the queue's order preservation
+ */
+#define DPSECI_QUEUE_OPT_ORDER_PRESERVATION 0x00000004
+
+/**
+ * struct dpseci_rx_queue_cfg - DPSECI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ * Use any combination of 'DPSECI_QUEUE_OPT_<X>' flags
+ * @order_preservation_en: order preservation configuration for the rx queue
+ * valid only if 'DPSECI_QUEUE_OPT_ORDER_PRESERVATION' is contained in 'options'
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame;
+ * valid only if 'DPSECI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ * valid only if 'DPSECI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpseci_rx_queue_cfg {
+ uint32_t options;
+ int order_preservation_en;
+ uint64_t user_ctx;
+ struct dpseci_dest_cfg dest_cfg;
+};
+
+/**
+ * dpseci_set_rx_queue() - Set Rx queue configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation; use
+ * DPSECI_ALL_QUEUES to configure all Rx queues identically.
+ * @cfg: Rx queue configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ const struct dpseci_rx_queue_cfg *cfg);
+
+/**
+ * struct dpseci_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame
+ * @order_preservation_en: Status of the order preservation configuration
+ * on the queue
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpseci_rx_queue_attr {
+ uint64_t user_ctx;
+ int order_preservation_en;
+ struct dpseci_dest_cfg dest_cfg;
+ uint32_t fqid;
+};
+
+/**
+ * dpseci_get_rx_queue() - Retrieve Rx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Rx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_rx_queue_attr *attr);
+
+/**
+ * struct dpseci_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to SEC hardware
+ * @priority: SEC hardware processing priority for the queue
+ */
+struct dpseci_tx_queue_attr {
+ uint32_t fqid;
+ uint8_t priority;
+};
+
+/**
+ * dpseci_get_tx_queue() - Retrieve Tx queue attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @queue: Select the queue relative to number of
+ * priorities configured at DPSECI creation
+ * @attr: Returned Tx queue attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t queue,
+ struct dpseci_tx_queue_attr *attr);
+
+/**
+ * struct dpseci_sec_attr - Structure representing attributes of the SEC
+ * hardware accelerator
+ * @ip_id: ID for SEC.
+ * @major_rev: Major revision number for SEC.
+ * @minor_rev: Minor revision number for SEC.
+ * @era: SEC Era.
+ * @deco_num: The number of copies of the DECO that are implemented in
+ * this version of SEC.
+ * @zuc_auth_acc_num: The number of copies of ZUCA that are implemented
+ * in this version of SEC.
+ * @zuc_enc_acc_num: The number of copies of ZUCE that are implemented
+ * in this version of SEC.
+ * @snow_f8_acc_num: The number of copies of the SNOW-f8 module that are
+ * implemented in this version of SEC.
+ * @snow_f9_acc_num: The number of copies of the SNOW-f9 module that are
+ * implemented in this version of SEC.
+ * @crc_acc_num: The number of copies of the CRC module that are implemented
+ * in this version of SEC.
+ * @pk_acc_num: The number of copies of the Public Key module that are
+ * implemented in this version of SEC.
+ * @kasumi_acc_num: The number of copies of the Kasumi module that are
+ * implemented in this version of SEC.
+ * @rng_acc_num: The number of copies of the Random Number Generator that are
+ * implemented in this version of SEC.
+ * @md_acc_num: The number of copies of the MDHA (Hashing module) that are
+ * implemented in this version of SEC.
+ * @arc4_acc_num: The number of copies of the ARC4 module that are implemented
+ * in this version of SEC.
+ * @des_acc_num: The number of copies of the DES module that are implemented
+ * in this version of SEC.
+ * @aes_acc_num: The number of copies of the AES module that are implemented
+ * in this version of SEC.
+ **/
+
+struct dpseci_sec_attr {
+ uint16_t ip_id;
+ uint8_t major_rev;
+ uint8_t minor_rev;
+ uint8_t era;
+ uint8_t deco_num;
+ uint8_t zuc_auth_acc_num;
+ uint8_t zuc_enc_acc_num;
+ uint8_t snow_f8_acc_num;
+ uint8_t snow_f9_acc_num;
+ uint8_t crc_acc_num;
+ uint8_t pk_acc_num;
+ uint8_t kasumi_acc_num;
+ uint8_t rng_acc_num;
+ uint8_t md_acc_num;
+ uint8_t arc4_acc_num;
+ uint8_t des_acc_num;
+ uint8_t aes_acc_num;
+};
+
+/**
+ * dpseci_get_sec_attr() - Retrieve SEC accelerator attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @attr: Returned SEC attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_attr *attr);
+
+/**
+ * struct dpseci_sec_counters - Structure representing global SEC counters and
+ * not per dpseci counters
+ * @dequeued_requests: Number of Requests Dequeued
+ * @ob_enc_requests: Number of Outbound Encrypt Requests
+ * @ib_dec_requests: Number of Inbound Decrypt Requests
+ * @ob_enc_bytes: Number of Outbound Bytes Encrypted
+ * @ob_prot_bytes: Number of Outbound Bytes Protected
+ * @ib_dec_bytes: Number of Inbound Bytes Decrypted
+ * @ib_valid_bytes: Number of Inbound Bytes Validated
+ */
+struct dpseci_sec_counters {
+ uint64_t dequeued_requests;
+ uint64_t ob_enc_requests;
+ uint64_t ib_dec_requests;
+ uint64_t ob_enc_bytes;
+ uint64_t ob_prot_bytes;
+ uint64_t ib_dec_bytes;
+ uint64_t ib_valid_bytes;
+};
+
+/**
+ * dpseci_get_sec_counters() - Retrieve SEC accelerator counters.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPSECI object
+ * @counters: Returned SEC counters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpseci_sec_counters *counters);
+
+/**
+ * dpseci_get_api_version() - Get Data Path SEC Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path sec API
+ * @minor_ver: Minor version of data path sec API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpseci_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPSECI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
new file mode 100644
index 0000000..97494f4
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
@@ -0,0 +1,255 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPSECI_CMD_H
+#define _FSL_DPSECI_CMD_H
+
+/* DPSECI Version */
+#define DPSECI_VER_MAJOR 5
+#define DPSECI_VER_MINOR 0
+
+/* Command IDs */
+#define DPSECI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPSECI_CMDID_OPEN ((0x809 << 4) | (0x1))
+#define DPSECI_CMDID_CREATE ((0x909 << 4) | (0x1))
+#define DPSECI_CMDID_DESTROY ((0x989 << 4) | (0x1))
+#define DPSECI_CMDID_GET_API_VERSION ((0xa09 << 4) | (0x1))
+
+#define DPSECI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPSECI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPSECI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPSECI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPSECI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_IRQ ((0x010 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ ((0x011 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_ENABLE ((0x012 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_ENABLE ((0x013 << 4) | (0x1))
+#define DPSECI_CMDID_SET_IRQ_MASK ((0x014 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_MASK ((0x015 << 4) | (0x1))
+#define DPSECI_CMDID_GET_IRQ_STATUS ((0x016 << 4) | (0x1))
+#define DPSECI_CMDID_CLEAR_IRQ_STATUS ((0x017 << 4) | (0x1))
+
+#define DPSECI_CMDID_SET_RX_QUEUE ((0x194 << 4) | (0x1))
+#define DPSECI_CMDID_GET_RX_QUEUE ((0x196 << 4) | (0x1))
+#define DPSECI_CMDID_GET_TX_QUEUE ((0x197 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_ATTR ((0x198 << 4) | (0x1))
+#define DPSECI_CMDID_GET_SEC_COUNTERS ((0x199 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_OPEN(cmd, dpseci_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpseci_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->priorities[0]);\
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, cfg->priorities[1]);\
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->priorities[2]);\
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->priorities[3]);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->priorities[4]);\
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->priorities[5]);\
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->priorities[6]);\
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->priorities[7]);\
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->num_tx_queues);\
+ MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->num_rx_queues);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ(cmd, type, irq_cfg) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
+ MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
+ MC_RSP_OP(cmd, 2, 32, 32, int, type); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_ENABLE(cmd, irq_index, enable_state) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, enable_state); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, enable_state)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_MASK(cmd, irq_index) \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_MASK(cmd, mask) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_IRQ_STATUS(cmd, status) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->num_tx_queues); \
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->num_rx_queues); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_SET_RX_QUEUE(cmd, queue, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue); \
+ MC_CMD_OP(cmd, 0, 48, 4, enum dpseci_dest, cfg->dest_cfg.dest_type); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
+ MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\
+ MC_CMD_OP(cmd, 2, 32, 1, int, cfg->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_RX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_RX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 48, 4, enum dpseci_dest, attr->dest_cfg.dest_type);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint64_t, attr->user_ctx);\
+ MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 2, 32, 1, int, attr->order_preservation_en);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_CMD_GET_TX_QUEUE(cmd, queue) \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, queue)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_TX_QUEUE(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, attr->fqid);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->priority);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, attr->ip_id);\
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->major_rev);\
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, attr->minor_rev);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->era);\
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, attr->deco_num);\
+ MC_RSP_OP(cmd, 1, 8, 8, uint8_t, attr->zuc_auth_acc_num);\
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, attr->zuc_enc_acc_num);\
+ MC_RSP_OP(cmd, 1, 32, 8, uint8_t, attr->snow_f8_acc_num);\
+ MC_RSP_OP(cmd, 1, 40, 8, uint8_t, attr->snow_f9_acc_num);\
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, attr->crc_acc_num);\
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->pk_acc_num);\
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->kasumi_acc_num);\
+ MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->rng_acc_num);\
+ MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->md_acc_num);\
+ MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->arc4_acc_num);\
+ MC_RSP_OP(cmd, 2, 48, 8, uint8_t, attr->des_acc_num);\
+ MC_RSP_OP(cmd, 2, 56, 8, uint8_t, attr->aes_acc_num);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_SEC_COUNTERS(cmd, counters) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, counters->dequeued_requests);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counters->ob_enc_requests);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, counters->ib_dec_requests);\
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, counters->ob_enc_bytes);\
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, counters->ob_prot_bytes);\
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, counters->ib_dec_bytes);\
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, counters->ib_valid_bytes);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPSECI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPSECI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 5167262..c4b3408 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -35,6 +35,16 @@ DPDK_17.02 {
dpni_set_rx_tc_dist;
dpni_set_tx_confirmation_mode;
dpni_set_unicast_promisc;
+ dpseci_close;
+ dpseci_disable;
+ dpseci_enable;
+ dpseci_get_attributes;
+ dpseci_get_rx_queue;
+ dpseci_get_sec_counters;
+ dpseci_get_tx_queue;
+ dpseci_open;
+ dpseci_reset;
+ dpseci_set_rx_queue;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 10/47] eal/vfio: adding vfio utility functions in map file
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (8 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 09/47] bus/fslmc: add mc dpseci " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 11/47] bus/fslmc: add vfio support Hemant Agrawal
` (38 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
adding extra vfio utility functions to map file.
They will be used by other vfio supported buses like fslmc bus
for NXP DPAA2 devices
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +++
2 files changed, 6 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2cf1ac8..a74625a 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -183,5 +183,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 3c68ff5..99d4446 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -187,5 +187,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 11/47] bus/fslmc: add vfio support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (9 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 10/47] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 12/47] bus/fslmc: scan for net and sec devices Hemant Agrawal
` (37 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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>
---
drivers/bus/fslmc/Makefile | 2 +
drivers/bus/fslmc/fslmc_bus.c | 10 +
drivers/bus/fslmc/fslmc_vfio.c | 450 ++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 74 +++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
5 files changed, 537 insertions(+)
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 4a118a3..7cccc0e 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_bus_fslmc_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 8a4f519..ee794e7 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -42,6 +42,7 @@
#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)
@@ -51,6 +52,15 @@
static int
rte_fslmc_scan(void)
{
+ if (fslmc_vfio_setup_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup VFIO");
+ return -1;
+ }
+ if (fslmc_vfio_process_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
+ return -1;
+ }
+ 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
new file mode 100644
index 0000000..73db595
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -0,0 +1,450 @@
+/*-
+ * 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_FSL_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 *(*rte_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, ®_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(void)
+{
+ 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 */
+ rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
+ if (!rte_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);
+
+ rte_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)
+{
+ struct fslmc_vfio_group *group = NULL;
+ int groupid;
+ int ret, 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;
+ }
+ /* get group number */
+ ret = vfio_get_group_no(SYSFS_FSL_MC_DEVICES, container, &groupid);
+ if (ret == 0) {
+ RTE_LOG(WARNING, EAL, "%s not managed by VFIO, skipping\n",
+ container);
+ return 1;
+ }
+
+ /* if negative, something failed */
+ if (ret < 0)
+ return -1;
+
+ 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;
+ }
+ }
+
+ /* get the actual group fd */
+ group->fd = vfio_get_group_fd(groupid);
+ if (group->fd < 0)
+ return -1;
+
+ /*
+ * at this point, we know that this group is viable (meaning,
+ * all devices are either bound to VFIO or not bound to anything)
+ */
+
+ 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..5e58211
--- /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(void);
+
+#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index c4b3408..23aff2e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -47,6 +47,7 @@ DPDK_17.02 {
dpseci_set_rx_queue;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_mcp_ptr_list;
local: *;
};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 12/47] bus/fslmc: scan for net and sec devices
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (10 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 11/47] bus/fslmc: add vfio support Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 13/47] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (36 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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_vfio.c | 63 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 73db595..0d4c0a2 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -210,6 +210,48 @@ 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 != DPAA2_MC_DPNI_DEVID ||
+ dev->dev_type != DPAA2_MC_DPSECI_DEVID)
+ return -1;
+
+ if (dev->object_id == dev2->object_id)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+fslmc_bus_add_device(struct rte_dpaa2_device *dev)
+{
+ struct rte_fslmc_device_list *dev_l;
+
+ dev_l = &rte_fslmc_bus.device_list;
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(dev_l)) {
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ } else {
+ struct rte_dpaa2_device *dev2;
+ int ret;
+
+ TAILQ_FOREACH(dev2, dev_l, next) {
+ ret = dpaa2_compare_dpaa2_dev(dev, dev2);
+ if (ret <= 0)
+ continue;
+
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ return;
+ }
+
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ }
+}
+
/* Following function shall fetch total available list of MC devices
* from VFIO container & populate private list of devices and other
* data structures
@@ -218,7 +260,7 @@ int fslmc_vfio_process_group(void)
{
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;
@@ -348,6 +390,25 @@ int fslmc_vfio_process_group(void)
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);
+
+ fslmc_bus_add_device(dev);
+ }
}
closedir(d);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 13/47] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (11 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 12/47] bus/fslmc: scan for net and sec devices Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 14/47] doc: add DPAA2 NIC details Hemant Agrawal
` (35 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/bus/Makefile | 2 +
drivers/bus/fslmc/Makefile | 4 +
drivers/common/Makefile | 4 +
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 61 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 142 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 3 +
14 files changed, 284 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/MAINTAINERS b/MAINTAINERS
index c151546..539f5f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -360,6 +360,7 @@ NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index d162228..11760a4 100644
--- a/config/common_base
+++ b/config/common_base
@@ -292,6 +292,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=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 365ae5a..e63ff56 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -46,3 +46,8 @@ CONFIG_RTE_MAX_NUMA_NODES=1
# 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/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 7cccc0e..ce799da 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -35,6 +35,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_bus_fslmc.a
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
CFLAGS += "-Wno-strict-aliasing"
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index cba1134..b52931c 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
index 9681729..87f08bb 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 7ac1ba7..18bca6b 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -36,6 +36,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_common_dpaa2_qbman.a
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 40fc333..c2f64ce 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
DIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
@@ -57,7 +58,6 @@ 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
-
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..c6a2764
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,61 @@
+# BSD LICENSE
+#
+# Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# Copyright (c) 2016 NXP. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Freescale Semiconductor, Inc nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+
+LDLIBS += -lrte_bus_fslmc
+
+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..bdef362
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,142 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = (struct eth_driver *)dpaa2_drv;
+
+ sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ sizeof(struct dpaa2_dev_priv),
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL) {
+ RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
+ " private port data\n");
+ rte_eth_dev_release_port(eth_dev);
+ 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;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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 92f3635..c327ade 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -108,6 +108,9 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_common_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 14/47] doc: add DPAA2 NIC details
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (12 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 13/47] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 15/47] bus/fslmc: add debug log support Hemant Agrawal
` (34 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 593 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
5 files changed, 615 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index 539f5f3..4f22942 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -361,6 +361,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..f0d7a26
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,593 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+This driver relies on external libraries and kernel drivers for resources
+allocations and initialization. The following dependencies are not part of
+DPDK and must be installed separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 87f9334..be21e8a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 357965a..a27f6b7 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -15,7 +15,6 @@ DPDK Release 17.02
firefox build/doc/html/guides/rel_notes/release_17_02.html
-
New Features
------------
@@ -250,6 +249,17 @@ New Features
See the :ref:`Elastic Flow Distributor Library <Efd_Library>` documentation in
the Programmers Guide document, for more information.
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
Resolved Issues
---------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 15/47] bus/fslmc: add debug log support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (13 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 14/47] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 16/47] net/dpaa2: " Hemant Agrawal
` (33 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 5 +++
drivers/bus/fslmc/fslmc_logs.h | 76 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index ce799da..77e0a1b 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -39,8 +39,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+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_ */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 16/47] net/dpaa2: add debug log support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (14 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 15/47] bus/fslmc: add debug log support Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 17/47] common/dpaa2: " Hemant Agrawal
` (32 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index c6a2764..966377a 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 bdef362..ead6a2c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -95,8 +100,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 17/47] common/dpaa2: add debug log support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (15 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 16/47] net/dpaa2: " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 18/47] config: enable support for DPAA2 debug logging Hemant Agrawal
` (31 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/common/dpaa2/qbman/Makefile | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 18bca6b..771bdc6 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -44,8 +44,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
+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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 18/47] config: enable support for DPAA2 debug logging
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (16 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 17/47] common/dpaa2: " Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 19/47] bus/fslmc: dpio portal driver Hemant Agrawal
` (30 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 11760a4..781d97b 100644
--- a/config/common_base
+++ b/config/common_base
@@ -295,6 +295,11 @@ 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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index e63ff56..eb12511 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -51,3 +51,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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 19/47] bus/fslmc: dpio portal driver
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (17 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 18/47] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 20/47] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
` (29 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The portal 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 | 5 +
drivers/bus/fslmc/fslmc_vfio.c | 17 +-
drivers/bus/fslmc/fslmc_vfio.h | 5 +
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 364 ++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 60 +++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 68 ++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
7 files changed, 520 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 77e0a1b..a26ba20 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ 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)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -65,10 +66,14 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpio.c \
mc/mc_sys.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
+
+LDLIBS += -lrte_common_dpaa2_qbman
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 0d4c0a2..2d7bcd9 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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
#define VFIO_MAX_CONTAINERS 1
#define FSLMC_VFIO_LOG(level, fmt, args...) \
@@ -261,12 +264,13 @@ int fslmc_vfio_process_group(void)
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;
@@ -409,9 +413,20 @@ int fslmc_vfio_process_group(void)
fslmc_bus_add_device(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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5e58211..39994dd 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -71,4 +71,9 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(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_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
new file mode 100644
index 0000000..dd6de4c
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+
+ reg_info.index = 0;
+ if (ioctl(dpio_dev->vfio_fd, VFIO_DEVICE_GET_REGION_INFO, ®_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, ®_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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
new file mode 100644
index 0000000..682f3fa
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -0,0 +1,60 @@
+/*-
+ * 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_DPIO_H_
+#define _DPAA2_HW_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);
+
+
+#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
new file mode 100644
index 0000000..6b44314
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 *(*rte_mcp_ptr_list);
+#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 23aff2e..48d776e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,7 @@
DPDK_17.02 {
global:
+ dpaa2_affine_qbman_swp;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
@@ -45,6 +46,7 @@ DPDK_17.02 {
dpseci_open;
dpseci_reset;
dpseci_set_rx_queue;
+ per_lcore__dpaa2_io;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
rte_mcp_ptr_list;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 20/47] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (18 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 19/47] bus/fslmc: dpio portal driver Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 21/47] bus/fslmc: affine dpio to crypto threads Hemant Agrawal
` (28 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +
drivers/Makefile | 1 +
drivers/bus/fslmc/Makefile | 2 +
drivers/bus/fslmc/fslmc_vfio.c | 9 +-
drivers/bus/fslmc/fslmc_vfio.h | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 +++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
drivers/common/Makefile | 4 +
drivers/common/dpaa2/Makefile | 4 +
drivers/common/dpaa2/qbman/Makefile | 4 +
drivers/pool/Makefile | 40 +++
drivers/pool/dpaa2/Makefile | 74 ++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339 ++++++++++++++++++++++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
mk/rte.app.mk | 1 +
19 files changed, 755 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
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_pool_dpaa2_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 4f22942..0bb0e3d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -361,6 +361,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
F: drivers/bus/fslmc/
F: drivers/common/dpaa2/
F: drivers/net/dpaa2/
+F: drivers/pool/dpaa2/
F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
diff --git a/config/common_base b/config/common_base
index 781d97b..664cafc 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,6 +287,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile Support Libraries for NXP DPAA2
+#
+CONFIG_RTE_LIBRTE_DPAA2_POOL=n
+
+#
# Compile NXP DPAA2 FSL-MC Bus
#
CONFIG_RTE_LIBRTE_FSLMC_BUS=n
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index eb12511..3cdb31b 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -42,6 +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_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..9fd268e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += common
DIRS-y += bus
+DIRS-y += pool
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index a26ba20..7f37467 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -51,6 +51,7 @@ 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/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -67,6 +68,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 2d7bcd9..fc017fc 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -270,7 +270,7 @@ int fslmc_vfio_process_group(void)
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 +420,11 @@ int fslmc_vfio_process_group(void)
if (!ret)
dpio_count++;
}
+ if (!strcmp(object_type, "dpbp")) {
+ ret = dpaa2_create_dpbp_device(object_id);
+ if (!ret)
+ dpbp_count++;
+ }
}
closedir(d);
@@ -427,6 +432,8 @@ int fslmc_vfio_process_group(void)
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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 39994dd..80c6869 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -76,4 +76,6 @@ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
struct vfio_device_info *obj_info,
int object_id);
+int dpaa2_create_dpbp_device(int dpbp_id);
+
#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
new file mode 100644
index 0000000..894f632
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
@@ -0,0 +1,137 @@
+/*-
+ * 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_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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
+TAILQ_HEAD(dpbp_device_list, dpaa2_dpbp_dev);
+static struct dpbp_device_list *dpbp_dev_list; /*!< DPBP device list */
+
+int
+dpaa2_create_dpbp_device(
+ int dpbp_id)
+{
+ struct dpaa2_dpbp_dev *dpbp_node;
+ int ret;
+
+ if (!dpbp_dev_list) {
+ dpbp_dev_list = malloc(sizeof(struct dpbp_device_list));
+ if (!dpbp_dev_list) {
+ PMD_INIT_LOG(ERR, "Memory alloc failed in DPBP list\n");
+ return -1;
+ }
+ /* Initialize the DPBP List */
+ TAILQ_INIT(dpbp_dev_list);
+ }
+
+ /* Allocate DPAA2 dpbp handle */
+ dpbp_node = (struct dpaa2_dpbp_dev *)
+ malloc(sizeof(struct dpaa2_dpbp_dev));
+ if (!dpbp_node) {
+ PMD_INIT_LOG(ERR, "Memory allocation failed for DPBP Device");
+ return -1;
+ }
+
+ /* Open the dpbp object */
+ dpbp_node->dpbp.regs = rte_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;
+ rte_atomic16_init(&dpbp_node->in_use);
+
+ TAILQ_INSERT_HEAD(dpbp_dev_list, dpbp_node, next);
+
+ PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
+
+ return 0;
+}
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Get DPBP dev handle from list using index */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
+ break;
+ }
+
+ return dpbp_dev;
+}
+
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Match DPBP handle and mark it free */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev == dpbp) {
+ rte_atomic16_dec(&dpbp_dev->in_use);
+ return;
+ }
+ }
+}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 6b44314..ad2847f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -63,6 +70,19 @@ struct dpaa2_dpio_dev {
int32_t hw_id; /**< An unique ID of this DPIO device instance */
};
+struct dpaa2_dpbp_dev {
+ TAILQ_ENTRY(dpaa2_dpbp_dev) next;
+ /**< Pointer to Next device instance */
+ struct fsl_mc_io dpbp; /** handle to DPBP portal object */
+ uint16_t token;
+ rte_atomic16_t in_use;
+ uint32_t dpbp_id; /*HW ID for DPBP object */
+};
+
/*! Global MCP list */
extern void *(*rte_mcp_ptr_list);
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
+
#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 48d776e..028f55e 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,8 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_alloc_dpbp_dev;
+ dpaa2_free_dpbp_dev;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
diff --git a/drivers/common/Makefile b/drivers/common/Makefile
index b52931c..3d70e8a 100644
--- a/drivers/common/Makefile
+++ b/drivers/common/Makefile
@@ -35,6 +35,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/Makefile b/drivers/common/dpaa2/Makefile
index 87f08bb..35e9405 100644
--- a/drivers/common/dpaa2/Makefile
+++ b/drivers/common/dpaa2/Makefile
@@ -35,6 +35,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/common/dpaa2/qbman/Makefile b/drivers/common/dpaa2/qbman/Makefile
index 771bdc6..ee53ad7 100644
--- a/drivers/common/dpaa2/qbman/Makefile
+++ b/drivers/common/dpaa2/qbman/Makefile
@@ -40,6 +40,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
endif
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_POOL),y)
+CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_DPAA2_POOL)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
CONFIG_RTE_LIBRTE_DPAA2_COMMON = $(CONFIG_RTE_LIBRTE_FSLMC_BUS)
endif
diff --git a/drivers/pool/Makefile b/drivers/pool/Makefile
new file mode 100644
index 0000000..3efc336
--- /dev/null
+++ b/drivers/pool/Makefile
@@ -0,0 +1,40 @@
+# 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
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += 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..7b30b8c
--- /dev/null
+++ b/drivers/pool/dpaa2/Makefile
@@ -0,0 +1,74 @@
+# 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_pool_dpaa2.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+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_pool_dpaa2_version.map
+
+# Lbrary version
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += dpaa2_hw_mempool.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += drivers/common/dpaa2
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += drivers/bus/fslmc
+
+LDLIBS += -lrte_common_dpaa2_qbman
+LDLIBS += -lrte_bus_fslmc
+
+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..0c8de51
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -0,0 +1,339 @@
+/*-
+ * 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 <mc/fsl_dpbp.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+#include "dpaa2_hw_mempool.h"
+
+struct dpaa2_bp_info rte_dpaa2_bpid_info[MAX_BPID];
+static struct dpaa2_bp_list *h_bp_list;
+
+static int
+hw_mbuf_create_pool(struct rte_mempool *mp)
+{
+ struct dpaa2_bp_list *bp_list;
+ struct dpaa2_dpbp_dev *avail_dpbp;
+ struct dpbp_attr dpbp_attr;
+ uint32_t bpid;
+ int ret;
+
+ avail_dpbp = dpaa2_alloc_dpbp_dev();
+
+ if (!avail_dpbp) {
+ PMD_DRV_LOG(ERR, "DPAA2 resources not available");
+ return -1;
+ }
+
+ if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+ ret = dpaa2_affine_qbman_swp();
+ if (ret) {
+ RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+ return 0;
+ }
+ }
+
+ 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;
+
+
+ rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
+ + rte_pktmbuf_priv_size(mp);
+ rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
+ rte_dpaa2_bpid_info[bpid].bpid = bpid;
+
+ mp->pool_data = (void *)&rte_dpaa2_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)
+{
+ struct dpaa2_bp_info *bpinfo;
+ struct dpaa2_bp_list *bp;
+ struct dpaa2_dpbp_dev *dpbp_node;
+
+ if (!mp->pool_data) {
+ PMD_DRV_LOG(ERR, "Not a valid dpaa22 pool");
+ return;
+ }
+
+ bpinfo = (struct dpaa2_bp_info *)mp->pool_data;
+ bp = bpinfo->bp_list;
+ dpbp_node = bp->buf_pool.dpbp_node;
+
+ dpbp_disable(&(dpbp_node->dpbp), CMD_PRI_LOW, dpbp_node->token);
+
+ if (h_bp_list == bp) {
+ h_bp_list = h_bp_list->next;
+ } else { /* if it is not the first node */
+ struct dpaa2_bp_list *prev = h_bp_list, *temp;
+ temp = h_bp_list->next;
+ while (temp) {
+ if (temp == bp) {
+ prev->next = temp->next;
+ free(bp);
+ break;
+ }
+ prev = temp;
+ temp = temp->next;
+ }
+ }
+
+ dpaa2_free_dpbp_dev(dpbp_node);
+}
+
+static
+void rte_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 rte_dpaa2_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 */
+ rte_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;
+ }
+ rte_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 = rte_dpaa2_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..c0e2411
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
@@ -0,0 +1,95 @@
+/*-
+ * 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 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 dpaa2_dpbp_dev *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 rte_dpaa2_bpid_info[MAX_BPID];
+
+int rte_dpaa2_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_pool_dpaa2_version.map b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
new file mode 100644
index 0000000..187f092
--- /dev/null
+++ b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
@@ -0,0 +1,8 @@
+DPDK_17.02 {
+ global:
+
+ rte_dpaa2_bpid_info;
+ rte_dpaa2_mbuf_alloc_bulk;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c327ade..c7d97c1 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -110,6 +110,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_common_dpaa2_qbman
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pool_dpaa2
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 21/47] bus/fslmc: affine dpio to crypto threads
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (19 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 20/47] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 22/47] bus/fslmc: define queues for DPAA2 devices Hemant Agrawal
` (27 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 45 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 3 ++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
3 files changed, 49 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index dd6de4c..bd1f643 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index 682f3fa..b1a1b8f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -56,5 +56,8 @@ 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);
+
#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 028f55e..4a8f478 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,7 @@ DPDK_17.02 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
dpaa2_free_dpbp_dev;
dpbp_disable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 22/47] bus/fslmc: define queues for DPAA2 devices
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (20 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 21/47] bus/fslmc: affine dpio to crypto threads Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 23/47] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (26 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Before DPAA2 devices can communicate using hardware queues, this patch
adds queue definitions in the FSLMC bus which the DPAA2 devices would
instantitate.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index ad2847f..42c5517 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -79,6 +82,23 @@ struct dpaa2_dpbp_dev {
uint32_t dpbp_id; /*HW ID for DPBP object */
};
+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 *(*rte_mcp_ptr_list);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 23/47] net/dpaa2: adding eth ops to dpaa2
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (21 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 22/47] bus/fslmc: define queues for DPAA2 devices Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 24/47] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (25 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 4 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 429 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 966377a..6eb1e0b 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -46,6 +46,8 @@ 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
@@ -59,8 +61,10 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+LDLIBS += -lrte_common_dpaa2_qbman
LDLIBS += -lrte_bus_fslmc
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index ead6a2c..934755a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 24/47] net/dpaa2: add RSS flow distribution
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (22 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 23/47] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 25/47] net/dpaa2: configure MAC address at init Hemant Agrawal
` (24 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 6eb1e0b..abd1fc8 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 934755a..c14b4df 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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;
priv->hw = dpni_dev;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 25/47] net/dpaa2: configure MAC address at init
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (23 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 24/47] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 26/47] bus/fslmc: define hardware annotation area size Hemant Agrawal
` (23 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 c14b4df..ab9dfe6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -443,6 +444,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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 26/47] bus/fslmc: define hardware annotation area size
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (24 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 25/47] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 27/47] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (22 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 42c5517..8efac2d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 27/47] net/dpaa2: attach the buffer pool to dpni
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (25 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 26/47] bus/fslmc: define hardware annotation area size Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 28/47] bus/fslmc: introduce true and false macros Hemant Agrawal
` (21 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/net/dpaa2/Makefile | 4 +++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 57 +++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 62 ++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 6 ++++
4 files changed, 129 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index abd1fc8..dc4d98a 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/bus/fslmc/portal
CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -62,10 +63,13 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/common/dpaa2
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/pool/dpaa2
LDLIBS += -lrte_common_dpaa2_qbman
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_pool_dpaa2
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 ab9dfe6..906a4d9 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -475,6 +488,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 28/47] bus/fslmc: introduce true and false macros
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (26 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 27/47] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 29/47] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (20 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 8efac2d..1af93a5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 29/47] net/dpaa2: add support for L3 and L4 checksum offload
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (27 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 28/47] bus/fslmc: introduce true and false macros Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 30/47] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (19 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 906a4d9..763c574 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 30/47] net/dpaa2: add support for promiscuous mode
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (28 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 29/47] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 31/47] bus/fslmc: define VLAN header length Hemant Agrawal
` (18 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 763c574..05c7e94 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 31/47] bus/fslmc: define VLAN header length
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (29 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 30/47] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 32/47] net/dpaa2: add MTU configuration support Hemant Agrawal
` (17 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1af93a5..2a8d9e5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 32/47] net/dpaa2: add MTU configuration support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (30 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 31/47] bus/fslmc: define VLAN header length Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 33/47] bus/fslmc: add packet FLE definitions Hemant Agrawal
` (16 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 05c7e94..53987cf 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 33/47] bus/fslmc: add packet FLE definitions
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (31 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 32/47] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 34/47] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (15 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 53 +++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 2a8d9e5..c26360d3 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
@@ -122,6 +128,53 @@ struct dpaa2_queue {
/*! Global MCP list */
extern void *(*rte_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
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 34/47] net/dpaa2: enable packet Rx and Tx operations
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (32 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 33/47] bus/fslmc: add packet FLE definitions Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 35/47] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (14 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index dc4d98a..5b1613c 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 53987cf..93ca0fa 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 35/47] net/dpaa2: support for Rx packet parsing and packet type
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (33 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 34/47] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 36/47] net/dpaa2: link status update Hemant Agrawal
` (13 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 93ca0fa..c4131e1 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 36/47] net/dpaa2: link status update
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (34 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 35/47] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 37/47] net/dpaa2: basic stats support Hemant Agrawal
` (12 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 c4131e1..14b9654 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 37/47] net/dpaa2: basic stats support
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (35 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 36/47] net/dpaa2: link status update Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 38/47] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (11 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 14b9654..1d6ae36 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 38/47] net/dpaa2: enable stashing for LS2088A devices
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (36 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 37/47] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 39/47] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (10 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 1d6ae36..64f41d9 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 39/47] net/dpaa2: handle non-hardware backed buffer pool
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (37 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 38/47] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 40/47] bus/fslmc: add physical-virtual address translation helpers Hemant Agrawal
` (9 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..a94761c 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_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),
+ rte_dpaa2_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 +380,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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 40/47] bus/fslmc: add physical-virtual address translation helpers
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (38 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 39/47] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 41/47] pool/dpaa2: enable physical addressing for pool buffers Hemant Agrawal
` (8 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 66 +++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index c26360d3..ad8a22f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -175,6 +175,72 @@ 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 */
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 41/47] pool/dpaa2: enable physical addressing for pool buffers
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (39 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 40/47] bus/fslmc: add physical-virtual address translation helpers Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 42/47] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (7 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/pool/dpaa2/dpaa2_hw_mempool.c b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
index 0c8de51..ca42418 100644
--- a/drivers/pool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -203,9 +203,14 @@ void rte_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);
@@ -214,8 +219,15 @@ void rte_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,
@@ -288,6 +300,7 @@ int rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 42/47] net/dpaa2: enable physical addressing for packet buffers
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (40 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 41/47] pool/dpaa2: enable physical addressing for pool buffers Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 43/47] config: add configuration for toggling physical addressing Hemant Agrawal
` (6 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 a94761c..49b4558 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 43/47] config: add configuration for toggling physical addressing
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (41 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 42/47] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 44/47] bus/fslmc: add support for DMA mapping for ARM SMMU Hemant Agrawal
` (5 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index 664cafc..3f5a356 100644
--- a/config/common_base
+++ b/config/common_base
@@ -290,6 +290,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
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 3cdb31b..29a56c7 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 44/47] bus/fslmc: add support for DMA mapping for ARM SMMU
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (42 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 43/47] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 45/47] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (4 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 96 +++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 1 +
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
3 files changed, 98 insertions(+)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index fc017fc..5f1d1b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -76,8 +76,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 *(*rte_mcp_ptr_list);
static uint32_t mcp_id;
+static int is_dma_done;
static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
{
@@ -147,6 +149,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,71 @@ int vfio_dmamap_mem_region(uint64_t vaddr,
return 0;
}
+int rte_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 80c6869..53dd0b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -70,6 +70,7 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(void);
+int rte_fslmc_vfio_dmamap(void);
/* create dpio device */
int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4a8f478..505873a 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -52,6 +52,7 @@ DPDK_17.02 {
per_lcore__dpaa2_io;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_fslmc_vfio_dmamap;
rte_mcp_ptr_list;
local: *;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 45/47] net/dpaa2: enable DMA Mapping during device scanning
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (43 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 44/47] bus/fslmc: add support for DMA mapping for ARM SMMU Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 46/47] bus/fslmc: frame queue based dq storage alloc Hemant Agrawal
` (3 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 64f41d9..6dddc3b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 46/47] bus/fslmc: frame queue based dq storage alloc
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (44 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 45/47] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 47/47] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
` (2 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/bus/fslmc/portal/dpaa2_hw_dpio.c | 32 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 7 +++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 ++
3 files changed, 41 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index bd1f643..c80d6c5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index b1a1b8f..f2e1168 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -59,5 +59,12 @@ struct dpaa2_io_portal_t {
/* Affine additional DPIO portal to current crypto processing thread */
int dpaa2_affine_qbman_swp_sec(void);
+/* 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/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 505873a..4298d77 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -4,7 +4,9 @@ DPDK_17.02 {
dpaa2_affine_qbman_swp;
dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
+ dpaa2_alloc_dq_storage;
dpaa2_free_dpbp_dev;
+ dpaa2_free_dq_storage;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv7 47/47] net/dpaa2: enable frame queue based dequeuing
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (45 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 46/47] bus/fslmc: frame queue based dq storage alloc Hemant Agrawal
@ 2017-02-16 0:39 ` Hemant Agrawal
2017-02-16 13:22 ` [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD Neil Horman
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-16 0:39 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 6dddc3b..c6ee406 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (46 preceding siblings ...)
2017-02-16 0:39 ` [dpdk-dev] [PATCHv7 47/47] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-02-16 13:22 ` Neil Horman
2017-02-16 13:27 ` Bruce Richardson
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
48 siblings, 1 reply; 549+ messages in thread
From: Neil Horman @ 2017-02-16 13:22 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, thomas.monjalon, bruce.richardson, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> fsl-mc bus driver and network SoC PMD. This version of the driver
> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
>
> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> designed for high-speed network packet processing. It uses a bus name
> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
>
> A brief description of architecture is given below; detailed description
> is part of the documentation in the patches itself.
>
> DPAA2 contains hardware component called the Management Complex (or MC).
> It manages the DPAA2 hardware resources. The MC provides an object-based
> abstraction for software drivers to use the DPAA2 hardware.
>
> Some of the key objects are:
> - DPNI, which refers to the network interface object.
> - DPBP, which refers to HW based memory pool object
> - DPIO, refers to processing context for accessing QBMAN
>
> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> software/user-space to the queues and buffers implemented in the hardware.
>
> The patch series could be logically structured into following sub-areas:
> 1. Make file changes for crc in armv8 core machine type and driver dependency
> 2. Common dpaa2 hw accelerator drivers for QBMAN.
> 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
> 4. Introducing dpaa2 pmd driver
> 5. Introducing dpaa2 mempool
> 6. Support for DPAA2 Ethernet Device (ethdev)
> 7. Additional functionality in DPAA2 ethdev.
>
> The following design decisions are made during development:
>
> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> These drivers will be shared with dpaa2 based crypto drivers.
>
> 2. DPAA2 implements the HW mempool offload with DPBP object.
> - The new pool is being configured using compile time option and pool name
> as "dpaa2".
>
> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> processing threads accessing the QBMAN HW.
>
> Prerequisites:
> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> Information about obtaining relevant software is available in the docs
> as part of the patch.
NAK. The SDK requires registration to obtain, and appears to be non-open
source. This driver is unmaintainable given that.
Neil
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-16 13:22 ` [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD Neil Horman
@ 2017-02-16 13:27 ` Bruce Richardson
2017-02-17 11:34 ` Ferruh Yigit
2017-02-17 12:29 ` Hemant Agrawal
0 siblings, 2 replies; 549+ messages in thread
From: Bruce Richardson @ 2017-02-16 13:27 UTC (permalink / raw)
To: Neil Horman
Cc: Hemant Agrawal, dev, thomas.monjalon, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> > The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> > fsl-mc bus driver and network SoC PMD. This version of the driver
> > supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
> >
> > DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> > designed for high-speed network packet processing. It uses a bus name
> > ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
> >
> > A brief description of architecture is given below; detailed description
> > is part of the documentation in the patches itself.
> >
> > DPAA2 contains hardware component called the Management Complex (or MC).
> > It manages the DPAA2 hardware resources. The MC provides an object-based
> > abstraction for software drivers to use the DPAA2 hardware.
> >
> > Some of the key objects are:
> > - DPNI, which refers to the network interface object.
> > - DPBP, which refers to HW based memory pool object
> > - DPIO, refers to processing context for accessing QBMAN
> >
> > Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> > called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> > software/user-space to the queues and buffers implemented in the hardware.
> >
> > The patch series could be logically structured into following sub-areas:
> > 1. Make file changes for crc in armv8 core machine type and driver dependency
> > 2. Common dpaa2 hw accelerator drivers for QBMAN.
> > 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
> > 4. Introducing dpaa2 pmd driver
> > 5. Introducing dpaa2 mempool
> > 6. Support for DPAA2 Ethernet Device (ethdev)
> > 7. Additional functionality in DPAA2 ethdev.
> >
> > The following design decisions are made during development:
> >
> > 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> > These drivers will be shared with dpaa2 based crypto drivers.
> >
> > 2. DPAA2 implements the HW mempool offload with DPBP object.
> > - The new pool is being configured using compile time option and pool name
> > as "dpaa2".
> >
> > 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> > processing threads accessing the QBMAN HW.
> >
> > Prerequisites:
> > - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> > Information about obtaining relevant software is available in the docs
> > as part of the patch.
>
> NAK. The SDK requires registration to obtain, and appears to be non-open
> source. This driver is unmaintainable given that.
>
Hi Hemant,
can you perhaps clarify things here. What is the requirement to:
* build the driver/DPDK for the platform
* run applications using DPDK on the platform
Also what is the license/availability for those requirements.
/Bruce
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-16 13:27 ` Bruce Richardson
@ 2017-02-17 11:34 ` Ferruh Yigit
2017-02-17 12:13 ` Bruce Richardson
2017-02-17 12:29 ` Hemant Agrawal
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-02-17 11:34 UTC (permalink / raw)
To: Bruce Richardson, Neil Horman
Cc: Hemant Agrawal, dev, thomas.monjalon, shreyansh.jain,
john.mcnamara, jerin.jacob
On 2/16/2017 1:27 PM, Bruce Richardson wrote:
> On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
>> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
>>> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
>>> fsl-mc bus driver and network SoC PMD. This version of the driver
>>> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
>>>
>>> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
>>> designed for high-speed network packet processing. It uses a bus name
>>> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
>>>
>>> A brief description of architecture is given below; detailed description
>>> is part of the documentation in the patches itself.
>>>
>>> DPAA2 contains hardware component called the Management Complex (or MC).
>>> It manages the DPAA2 hardware resources. The MC provides an object-based
>>> abstraction for software drivers to use the DPAA2 hardware.
>>>
>>> Some of the key objects are:
>>> - DPNI, which refers to the network interface object.
>>> - DPBP, which refers to HW based memory pool object
>>> - DPIO, refers to processing context for accessing QBMAN
>>>
>>> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
>>> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
>>> software/user-space to the queues and buffers implemented in the hardware.
>>>
>>> The patch series could be logically structured into following sub-areas:
>>> 1. Make file changes for crc in armv8 core machine type and driver dependency
>>> 2. Common dpaa2 hw accelerator drivers for QBMAN.
>>> 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
>>> 4. Introducing dpaa2 pmd driver
>>> 5. Introducing dpaa2 mempool
>>> 6. Support for DPAA2 Ethernet Device (ethdev)
>>> 7. Additional functionality in DPAA2 ethdev.
>>>
>>> The following design decisions are made during development:
>>>
>>> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
>>> These drivers will be shared with dpaa2 based crypto drivers.
>>>
>>> 2. DPAA2 implements the HW mempool offload with DPBP object.
>>> - The new pool is being configured using compile time option and pool name
>>> as "dpaa2".
>>>
>>> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
>>> processing threads accessing the QBMAN HW.
>>>
>>> Prerequisites:
>>> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
>>> Information about obtaining relevant software is available in the docs
>>> as part of the patch.
>>
>> NAK. The SDK requires registration to obtain, and appears to be non-open
>> source. This driver is unmaintainable given that.
>>
> Hi Hemant,
>
> can you perhaps clarify things here. What is the requirement to:
> * build the driver/DPDK for the platform
> * run applications using DPDK on the platform
>
> Also what is the license/availability for those requirements.
Hi Bruce, Hemant, Neil, Thomas,
I did able to compile the driver without the SDK. It looks like that SDK
is a runtime dependency.
What is the DPDK requirement here?
If it is not breaking the build, this PMD provides it.
Thanks,
ferruh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-17 11:34 ` Ferruh Yigit
@ 2017-02-17 12:13 ` Bruce Richardson
2017-02-17 12:17 ` Vincent JARDIN
2017-02-17 13:40 ` Thomas Monjalon
0 siblings, 2 replies; 549+ messages in thread
From: Bruce Richardson @ 2017-02-17 12:13 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Neil Horman, Hemant Agrawal, dev, thomas.monjalon,
shreyansh.jain, john.mcnamara, jerin.jacob
On Fri, Feb 17, 2017 at 11:34:43AM +0000, Ferruh Yigit wrote:
> On 2/16/2017 1:27 PM, Bruce Richardson wrote:
> > On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
> >> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> >>> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> >>> fsl-mc bus driver and network SoC PMD. This version of the driver
> >>> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
> >>>
> >>> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> >>> designed for high-speed network packet processing. It uses a bus name
> >>> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
> >>>
> >>> A brief description of architecture is given below; detailed description
> >>> is part of the documentation in the patches itself.
> >>>
> >>> DPAA2 contains hardware component called the Management Complex (or MC).
> >>> It manages the DPAA2 hardware resources. The MC provides an object-based
> >>> abstraction for software drivers to use the DPAA2 hardware.
> >>>
> >>> Some of the key objects are:
> >>> - DPNI, which refers to the network interface object.
> >>> - DPBP, which refers to HW based memory pool object
> >>> - DPIO, refers to processing context for accessing QBMAN
> >>>
> >>> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> >>> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> >>> software/user-space to the queues and buffers implemented in the hardware.
> >>>
> >>> The patch series could be logically structured into following sub-areas:
> >>> 1. Make file changes for crc in armv8 core machine type and driver dependency
> >>> 2. Common dpaa2 hw accelerator drivers for QBMAN.
> >>> 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
> >>> 4. Introducing dpaa2 pmd driver
> >>> 5. Introducing dpaa2 mempool
> >>> 6. Support for DPAA2 Ethernet Device (ethdev)
> >>> 7. Additional functionality in DPAA2 ethdev.
> >>>
> >>> The following design decisions are made during development:
> >>>
> >>> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> >>> These drivers will be shared with dpaa2 based crypto drivers.
> >>>
> >>> 2. DPAA2 implements the HW mempool offload with DPBP object.
> >>> - The new pool is being configured using compile time option and pool name
> >>> as "dpaa2".
> >>>
> >>> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> >>> processing threads accessing the QBMAN HW.
> >>>
> >>> Prerequisites:
> >>> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> >>> Information about obtaining relevant software is available in the docs
> >>> as part of the patch.
> >>
> >> NAK. The SDK requires registration to obtain, and appears to be non-open
> >> source. This driver is unmaintainable given that.
> >>
> > Hi Hemant,
> >
> > can you perhaps clarify things here. What is the requirement to:
> > * build the driver/DPDK for the platform
> > * run applications using DPDK on the platform
> >
> > Also what is the license/availability for those requirements.
>
> Hi Bruce, Hemant, Neil, Thomas,
>
> I did able to compile the driver without the SDK. It looks like that SDK
> is a runtime dependency.
>
> What is the DPDK requirement here?
> If it is not breaking the build, this PMD provides it.
>
If it builds without an SDK dependency I'd be happy enough to see this
merged into DPDK. Since I can't run it without the correct hardware, I
don't see needing the correct runtime software being a difficulty too.
So long as we can compile this, we can check for breakages in it due to
refactoring in other parts of DPDK, like we do for other drivers. As
with those other drivers, it's up to the maintainers/vendors to do the
functional checking for additional issues. Nobody is likely to have the
hardware to functionality test all drivers in DPDK anyway.
Regards,
/Bruce
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-17 12:13 ` Bruce Richardson
@ 2017-02-17 12:17 ` Vincent JARDIN
2017-02-17 22:48 ` Neil Horman
2017-02-17 13:40 ` Thomas Monjalon
1 sibling, 1 reply; 549+ messages in thread
From: Vincent JARDIN @ 2017-02-17 12:17 UTC (permalink / raw)
To: Bruce Richardson, Ferruh Yigit
Cc: Neil Horman, Hemant Agrawal, dev, thomas.monjalon,
shreyansh.jain, john.mcnamara, jerin.jacob
Le 17/02/2017 à 13:13, Bruce Richardson a écrit :
> If it builds without an SDK dependency I'd be happy enough to see this
> merged into DPDK.
+1, the patch is clean enough to be compiled.
Boards or CPUs can rely on specific SDK, firmware, etc., it is up to the
vendors.
regards,
Vincent
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-17 12:17 ` Vincent JARDIN
@ 2017-02-17 22:48 ` Neil Horman
0 siblings, 0 replies; 549+ messages in thread
From: Neil Horman @ 2017-02-17 22:48 UTC (permalink / raw)
To: Vincent JARDIN
Cc: Bruce Richardson, Ferruh Yigit, Hemant Agrawal, dev,
thomas.monjalon, shreyansh.jain, john.mcnamara, jerin.jacob
On Fri, Feb 17, 2017 at 01:17:26PM +0100, Vincent JARDIN wrote:
> Le 17/02/2017 à 13:13, Bruce Richardson a écrit :
> > If it builds without an SDK dependency I'd be happy enough to see this
> > merged into DPDK.
>
> +1, the patch is clean enough to be compiled.
>
> Boards or CPUs can rely on specific SDK, firmware, etc., it is up to the
> vendors.
>
I absolutely disagree with this. Its completely anathema to the reason open
source code is beneficial to the community that maintains it. By allowing code
like this into the project, you've tacitly agree to do regular maintenence on
their code for them, without the reciprocating benefit of being able to use
their hardware free of additional license terms. If you want to have a non-open
driver that works with an open source project, thats fine, but keep it out of
tree, and maintain it yourself. What you've esentially asked for here is for
the dpdk community to be some free labor, when APIS and such change. No thank
you.
I re-iterate my NAK.
> regards,
> Vincent
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-17 12:13 ` Bruce Richardson
2017-02-17 12:17 ` Vincent JARDIN
@ 2017-02-17 13:40 ` Thomas Monjalon
1 sibling, 0 replies; 549+ messages in thread
From: Thomas Monjalon @ 2017-02-17 13:40 UTC (permalink / raw)
To: Bruce Richardson
Cc: Ferruh Yigit, Neil Horman, Hemant Agrawal, dev, shreyansh.jain,
john.mcnamara, jerin.jacob
2017-02-17 12:13, Bruce Richardson:
> On Fri, Feb 17, 2017 at 11:34:43AM +0000, Ferruh Yigit wrote:
> > On 2/16/2017 1:27 PM, Bruce Richardson wrote:
> > > On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
> > >> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> > >>> Prerequisites:
> > >>> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> > >>> Information about obtaining relevant software is available in the docs
> > >>> as part of the patch.
> > >>
> > >> NAK. The SDK requires registration to obtain, and appears to be non-open
> > >> source. This driver is unmaintainable given that.
> > >>
> > > Hi Hemant,
> > >
> > > can you perhaps clarify things here. What is the requirement to:
> > > * build the driver/DPDK for the platform
> > > * run applications using DPDK on the platform
> > >
> > > Also what is the license/availability for those requirements.
> >
> > Hi Bruce, Hemant, Neil, Thomas,
> >
> > I did able to compile the driver without the SDK. It looks like that SDK
> > is a runtime dependency.
> >
> > What is the DPDK requirement here?
> > If it is not breaking the build, this PMD provides it.
> >
> If it builds without an SDK dependency I'd be happy enough to see this
> merged into DPDK. Since I can't run it without the correct hardware, I
> don't see needing the correct runtime software being a difficulty too.
> So long as we can compile this, we can check for breakages in it due to
> refactoring in other parts of DPDK, like we do for other drivers. As
> with those other drivers, it's up to the maintainers/vendors to do the
> functional checking for additional issues. Nobody is likely to have the
> hardware to functionality test all drivers in DPDK anyway.
+1, I agree with Bruce
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-16 13:27 ` Bruce Richardson
2017-02-17 11:34 ` Ferruh Yigit
@ 2017-02-17 12:29 ` Hemant Agrawal
2017-02-19 14:44 ` Neil Horman
1 sibling, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-17 12:29 UTC (permalink / raw)
To: Bruce Richardson, Neil Horman
Cc: dev, thomas.monjalon, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
On 2/16/2017 6:57 PM, Bruce Richardson wrote:
> On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
>> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
>>> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
>>> fsl-mc bus driver and network SoC PMD. This version of the driver
>>> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
>>>
>>> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
>>> designed for high-speed network packet processing. It uses a bus name
>>> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
>>>
>>> A brief description of architecture is given below; detailed description
>>> is part of the documentation in the patches itself.
>>>
>>> DPAA2 contains hardware component called the Management Complex (or MC).
>>> It manages the DPAA2 hardware resources. The MC provides an object-based
>>> abstraction for software drivers to use the DPAA2 hardware.
>>>
>>> Some of the key objects are:
>>> - DPNI, which refers to the network interface object.
>>> - DPBP, which refers to HW based memory pool object
>>> - DPIO, refers to processing context for accessing QBMAN
>>>
>>> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
>>> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
>>> software/user-space to the queues and buffers implemented in the hardware.
>>>
>>> The patch series could be logically structured into following sub-areas:
>>> 1. Make file changes for crc in armv8 core machine type and driver dependency
>>> 2. Common dpaa2 hw accelerator drivers for QBMAN.
>>> 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
>>> 4. Introducing dpaa2 pmd driver
>>> 5. Introducing dpaa2 mempool
>>> 6. Support for DPAA2 Ethernet Device (ethdev)
>>> 7. Additional functionality in DPAA2 ethdev.
>>>
>>> The following design decisions are made during development:
>>>
>>> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
>>> These drivers will be shared with dpaa2 based crypto drivers.
>>>
>>> 2. DPAA2 implements the HW mempool offload with DPBP object.
>>> - The new pool is being configured using compile time option and pool name
>>> as "dpaa2".
>>>
>>> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
>>> processing threads accessing the QBMAN HW.
>>>
>>> Prerequisites:
>>> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
>>> Information about obtaining relevant software is available in the docs
>>> as part of the patch.
>>
>> NAK. The SDK requires registration to obtain, and appears to be non-open
>> source. This driver is unmaintainable given that.
>>
> Hi Hemant,
>
> can you perhaps clarify things here. What is the requirement to:
> * build the driver/DPDK for the platform
> * run applications using DPDK on the platform
>
> Also what is the license/availability for those requirements.
>
> /Bruce
Hi Neil, Bruce,
I thought SDK is a simpler choice to get the required components in one
place. However there is no such restriction to get the components only
from the NXP SDK.
We will update the documentation with the same.
Following is a list of open source components required:
1. ARM 64 tool chain.
e.g. *aarch64* Linaro Toolchain:
https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/
2. Linux Kernel
http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/log/?h=sdk-v2.0.x
or,
https://github.com/qoriq-open-source/linux
Please note that the particular linux kernel, I have used for my testing
is 4.1.8 (part of our SDK 2.0-17.01), I will publish the tree at github
shortly.
3. Rootfile system : any aarch64 supported e.g.
Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland
http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz
Initial kernel is best built in a Yocto build environment, then deployed
to target with a disk based Ubuntu userland.
However, both kernel and DPDK release can be natively built on the
target platform, using Ubuntu devtools.
Regards,
Hemant
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-17 12:29 ` Hemant Agrawal
@ 2017-02-19 14:44 ` Neil Horman
2017-02-20 5:31 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Neil Horman @ 2017-02-19 14:44 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Bruce Richardson, dev, thomas.monjalon, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On Fri, Feb 17, 2017 at 05:59:45PM +0530, Hemant Agrawal wrote:
> On 2/16/2017 6:57 PM, Bruce Richardson wrote:
> > On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
> > > On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> > > > The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> > > > fsl-mc bus driver and network SoC PMD. This version of the driver
> > > > supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
> > > >
> > > > DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> > > > designed for high-speed network packet processing. It uses a bus name
> > > > ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
> > > >
> > > > A brief description of architecture is given below; detailed description
> > > > is part of the documentation in the patches itself.
> > > >
> > > > DPAA2 contains hardware component called the Management Complex (or MC).
> > > > It manages the DPAA2 hardware resources. The MC provides an object-based
> > > > abstraction for software drivers to use the DPAA2 hardware.
> > > >
> > > > Some of the key objects are:
> > > > - DPNI, which refers to the network interface object.
> > > > - DPBP, which refers to HW based memory pool object
> > > > - DPIO, refers to processing context for accessing QBMAN
> > > >
> > > > Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> > > > called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> > > > software/user-space to the queues and buffers implemented in the hardware.
> > > >
> > > > The patch series could be logically structured into following sub-areas:
> > > > 1. Make file changes for crc in armv8 core machine type and driver dependency
> > > > 2. Common dpaa2 hw accelerator drivers for QBMAN.
> > > > 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
> > > > 4. Introducing dpaa2 pmd driver
> > > > 5. Introducing dpaa2 mempool
> > > > 6. Support for DPAA2 Ethernet Device (ethdev)
> > > > 7. Additional functionality in DPAA2 ethdev.
> > > >
> > > > The following design decisions are made during development:
> > > >
> > > > 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> > > > These drivers will be shared with dpaa2 based crypto drivers.
> > > >
> > > > 2. DPAA2 implements the HW mempool offload with DPBP object.
> > > > - The new pool is being configured using compile time option and pool name
> > > > as "dpaa2".
> > > >
> > > > 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> > > > processing threads accessing the QBMAN HW.
> > > >
> > > > Prerequisites:
> > > > - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> > > > Information about obtaining relevant software is available in the docs
> > > > as part of the patch.
> > >
> > > NAK. The SDK requires registration to obtain, and appears to be non-open
> > > source. This driver is unmaintainable given that.
> > >
> > Hi Hemant,
> >
> > can you perhaps clarify things here. What is the requirement to:
> > * build the driver/DPDK for the platform
> > * run applications using DPDK on the platform
> >
> > Also what is the license/availability for those requirements.
> >
> > /Bruce
>
>
> Hi Neil, Bruce,
> I thought SDK is a simpler choice to get the required components in one
> place. However there is no such restriction to get the components only from
> the NXP SDK.
> We will update the documentation with the same.
>
> Following is a list of open source components required:
>
> 1. ARM 64 tool chain.
> e.g. *aarch64* Linaro Toolchain:
> https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/
>
> 2. Linux Kernel
>
> http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/log/?h=sdk-v2.0.x
> or,
> https://github.com/qoriq-open-source/linux
> Please note that the particular linux kernel, I have used for my testing is
> 4.1.8 (part of our SDK 2.0-17.01), I will publish the tree at github
> shortly.
>
> 3. Rootfile system : any aarch64 supported e.g.
> Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland
> http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz
>
> Initial kernel is best built in a Yocto build environment, then deployed to
> target with a disk based Ubuntu userland.
> However, both kernel and DPDK release can be natively built on the target
> platform, using Ubuntu devtools.
>
Ok, so lets clarify this a bit with a question: Understanding that you
indicated you can build this pmd with host tools, are there any runtime
dependencies on the SDK? That is to say, can you build an run this pmd without
ever having to agree to the SDK usage policy? If so, then if you remove the
language suggesting such from your documentation patch, I rescind my nak.
Best
Neil
> Regards,
> Hemant
>
>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-19 14:44 ` Neil Horman
@ 2017-02-20 5:31 ` Hemant Agrawal
2017-02-20 12:20 ` Neil Horman
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-02-20 5:31 UTC (permalink / raw)
To: Neil Horman
Cc: Bruce Richardson, dev, thomas.monjalon, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On 2/19/2017 8:14 PM, Neil Horman wrote:
> On Fri, Feb 17, 2017 at 05:59:45PM +0530, Hemant Agrawal wrote:
>> On 2/16/2017 6:57 PM, Bruce Richardson wrote:
>>> On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
>>>> On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
>>>>> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
>>>>> fsl-mc bus driver and network SoC PMD. This version of the driver
>>>>> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
>>>>>
>>>>> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
>>>>> designed for high-speed network packet processing. It uses a bus name
>>>>> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
>>>>>
>>>>> A brief description of architecture is given below; detailed description
>>>>> is part of the documentation in the patches itself.
>>>>>
>>>>> DPAA2 contains hardware component called the Management Complex (or MC).
>>>>> It manages the DPAA2 hardware resources. The MC provides an object-based
>>>>> abstraction for software drivers to use the DPAA2 hardware.
>>>>>
>>>>> Some of the key objects are:
>>>>> - DPNI, which refers to the network interface object.
>>>>> - DPBP, which refers to HW based memory pool object
>>>>> - DPIO, refers to processing context for accessing QBMAN
>>>>>
>>>>> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
>>>>> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
>>>>> software/user-space to the queues and buffers implemented in the hardware.
>>>>>
>>>>> The patch series could be logically structured into following sub-areas:
>>>>> 1. Make file changes for crc in armv8 core machine type and driver dependency
>>>>> 2. Common dpaa2 hw accelerator drivers for QBMAN.
>>>>> 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
>>>>> 4. Introducing dpaa2 pmd driver
>>>>> 5. Introducing dpaa2 mempool
>>>>> 6. Support for DPAA2 Ethernet Device (ethdev)
>>>>> 7. Additional functionality in DPAA2 ethdev.
>>>>>
>>>>> The following design decisions are made during development:
>>>>>
>>>>> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
>>>>> These drivers will be shared with dpaa2 based crypto drivers.
>>>>>
>>>>> 2. DPAA2 implements the HW mempool offload with DPBP object.
>>>>> - The new pool is being configured using compile time option and pool name
>>>>> as "dpaa2".
>>>>>
>>>>> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
>>>>> processing threads accessing the QBMAN HW.
>>>>>
>>>>> Prerequisites:
>>>>> - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
>>>>> Information about obtaining relevant software is available in the docs
>>>>> as part of the patch.
>>>>
>>>> NAK. The SDK requires registration to obtain, and appears to be non-open
>>>> source. This driver is unmaintainable given that.
>>>>
>>> Hi Hemant,
>>>
>>> can you perhaps clarify things here. What is the requirement to:
>>> * build the driver/DPDK for the platform
>>> * run applications using DPDK on the platform
>>>
>>> Also what is the license/availability for those requirements.
>>>
>>> /Bruce
>>
>>
>> Hi Neil, Bruce,
>> I thought SDK is a simpler choice to get the required components in one
>> place. However there is no such restriction to get the components only from
>> the NXP SDK.
>> We will update the documentation with the same.
>>
>> Following is a list of open source components required:
>>
>> 1. ARM 64 tool chain.
>> e.g. *aarch64* Linaro Toolchain:
>> https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/
>>
>> 2. Linux Kernel
>>
>> http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/log/?h=sdk-v2.0.x
>> or,
>> https://github.com/qoriq-open-source/linux
>> Please note that the particular linux kernel, I have used for my testing is
>> 4.1.8 (part of our SDK 2.0-17.01), I will publish the tree at github
>> shortly.
>>
>> 3. Rootfile system : any aarch64 supported e.g.
>> Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland
>> http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz
>>
>
>> Initial kernel is best built in a Yocto build environment, then deployed to
>> target with a disk based Ubuntu userland.
>> However, both kernel and DPDK release can be natively built on the target
>> platform, using Ubuntu devtools.
>>
>
>
> Ok, so lets clarify this a bit with a question: Understanding that you
> indicated you can build this pmd with host tools, are there any runtime
> dependencies on the SDK? That is to say, can you build an run this pmd without
> ever having to agree to the SDK usage policy? If so, then if you remove the
> language suggesting such from your documentation patch, I rescind my nak.
>
Hi Neil,
yes! there is absolutely no need to use the SDK and agreeing to SDK
usages policy. All the components are available in open source and the
PMD can run using them.
As suggested, I will change my documentation patch.
Thanks for your comments.
Regards,
Hemant
> Best
> Neil
>
>> Regards,
>> Hemant
>>
>>
>>
>>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD
2017-02-20 5:31 ` Hemant Agrawal
@ 2017-02-20 12:20 ` Neil Horman
0 siblings, 0 replies; 549+ messages in thread
From: Neil Horman @ 2017-02-20 12:20 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Bruce Richardson, dev, thomas.monjalon, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On Mon, Feb 20, 2017 at 11:01:23AM +0530, Hemant Agrawal wrote:
> On 2/19/2017 8:14 PM, Neil Horman wrote:
> > On Fri, Feb 17, 2017 at 05:59:45PM +0530, Hemant Agrawal wrote:
> > > On 2/16/2017 6:57 PM, Bruce Richardson wrote:
> > > > On Thu, Feb 16, 2017 at 08:22:49AM -0500, Neil Horman wrote:
> > > > > On Thu, Feb 16, 2017 at 06:08:59AM +0530, Hemant Agrawal wrote:
> > > > > > The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> > > > > > fsl-mc bus driver and network SoC PMD. This version of the driver
> > > > > > supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
> > > > > >
> > > > > > DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> > > > > > designed for high-speed network packet processing. It uses a bus name
> > > > > > ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
> > > > > >
> > > > > > A brief description of architecture is given below; detailed description
> > > > > > is part of the documentation in the patches itself.
> > > > > >
> > > > > > DPAA2 contains hardware component called the Management Complex (or MC).
> > > > > > It manages the DPAA2 hardware resources. The MC provides an object-based
> > > > > > abstraction for software drivers to use the DPAA2 hardware.
> > > > > >
> > > > > > Some of the key objects are:
> > > > > > - DPNI, which refers to the network interface object.
> > > > > > - DPBP, which refers to HW based memory pool object
> > > > > > - DPIO, refers to processing context for accessing QBMAN
> > > > > >
> > > > > > Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> > > > > > called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> > > > > > software/user-space to the queues and buffers implemented in the hardware.
> > > > > >
> > > > > > The patch series could be logically structured into following sub-areas:
> > > > > > 1. Make file changes for crc in armv8 core machine type and driver dependency
> > > > > > 2. Common dpaa2 hw accelerator drivers for QBMAN.
> > > > > > 3. Indroducing fsl-mc bus as rte_bus, it's componenets.
> > > > > > 4. Introducing dpaa2 pmd driver
> > > > > > 5. Introducing dpaa2 mempool
> > > > > > 6. Support for DPAA2 Ethernet Device (ethdev)
> > > > > > 7. Additional functionality in DPAA2 ethdev.
> > > > > >
> > > > > > The following design decisions are made during development:
> > > > > >
> > > > > > 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> > > > > > These drivers will be shared with dpaa2 based crypto drivers.
> > > > > >
> > > > > > 2. DPAA2 implements the HW mempool offload with DPBP object.
> > > > > > - The new pool is being configured using compile time option and pool name
> > > > > > as "dpaa2".
> > > > > >
> > > > > > 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> > > > > > processing threads accessing the QBMAN HW.
> > > > > >
> > > > > > Prerequisites:
> > > > > > - For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
> > > > > > Information about obtaining relevant software is available in the docs
> > > > > > as part of the patch.
> > > > >
> > > > > NAK. The SDK requires registration to obtain, and appears to be non-open
> > > > > source. This driver is unmaintainable given that.
> > > > >
> > > > Hi Hemant,
> > > >
> > > > can you perhaps clarify things here. What is the requirement to:
> > > > * build the driver/DPDK for the platform
> > > > * run applications using DPDK on the platform
> > > >
> > > > Also what is the license/availability for those requirements.
> > > >
> > > > /Bruce
> > >
> > >
> > > Hi Neil, Bruce,
> > > I thought SDK is a simpler choice to get the required components in one
> > > place. However there is no such restriction to get the components only from
> > > the NXP SDK.
> > > We will update the documentation with the same.
> > >
> > > Following is a list of open source components required:
> > >
> > > 1. ARM 64 tool chain.
> > > e.g. *aarch64* Linaro Toolchain:
> > > https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/
> > >
> > > 2. Linux Kernel
> > >
> > > http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/log/?h=sdk-v2.0.x
> > > or,
> > > https://github.com/qoriq-open-source/linux
> > > Please note that the particular linux kernel, I have used for my testing is
> > > 4.1.8 (part of our SDK 2.0-17.01), I will publish the tree at github
> > > shortly.
> > >
> > > 3. Rootfile system : any aarch64 supported e.g.
> > > Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland
> > > http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz
> > >
> >
> > > Initial kernel is best built in a Yocto build environment, then deployed to
> > > target with a disk based Ubuntu userland.
> > > However, both kernel and DPDK release can be natively built on the target
> > > platform, using Ubuntu devtools.
> > >
> >
> >
> > Ok, so lets clarify this a bit with a question: Understanding that you
> > indicated you can build this pmd with host tools, are there any runtime
> > dependencies on the SDK? That is to say, can you build an run this pmd without
> > ever having to agree to the SDK usage policy? If so, then if you remove the
> > language suggesting such from your documentation patch, I rescind my nak.
> >
> Hi Neil,
> yes! there is absolutely no need to use the SDK and agreeing to SDK usages
> policy. All the components are available in open source and the PMD can run
> using them.
>
> As suggested, I will change my documentation patch.
>
> Thanks for your comments.
>
> Regards,
> Hemant
>
Then I have no problem with the driver, if you update the documentation
accordingly, I'll ack it.
Neil
>
> > Best
> > Neil
> >
> > > Regards,
> > > Hemant
> > >
> > >
> > >
> > >
> >
>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD
2017-02-16 0:38 ` [dpdk-dev] [PATCHv7 00/47] " Hemant Agrawal
` (47 preceding siblings ...)
2017-02-16 13:22 ` [dpdk-dev] [PATCHv7 00/47] NXP DPAA2 PMD Neil Horman
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 01/46] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
` (48 more replies)
48 siblings, 49 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
fsl-mc bus driver and network SoC PMD. This version of the driver
supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
A brief description of architecture is given below; detailed description
is part of the documentation in the patches itself.
DPAA2 contains hardware component called the Management Complex (or MC).
It manages the DPAA2 hardware resources. The MC provides an object-based
abstraction for software drivers to use the DPAA2 hardware.
Some of the key objects are:
- DPNI, which refers to the network interface object.
- DPBP, which refers to HW based memory pool object
- DPIO, refers to processing context for accessing QBMAN
Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
software/user-space to the queues and buffers implemented in the hardware.
The patch series could be logically structured into following sub-areas:
1. Make file changes for crc in armv8 core machine type and driver dependency
2. Indroducing fsl-mc bus as rte_bus, it's componenets.
3. Introducing dpaa2 pmd driver
4. Introducing dpaa2 mempool
5. Support for DPAA2 Ethernet Device (ethdev)
6. Additional functionality in DPAA2 ethdev.
The following design decisions are made during development:
1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
These drivers will be shared with dpaa2 based crypto drivers.
2. DPAA2 implements the HW mempool offload with DPBP object.
- The new pool is being configured using compile time option and pool name
as "dpaa2".
3. It maintains per lcore DPIO objects and affine the DPIO instance to the
processing threads accessing the QBMAN HW.
Prerequisites:
- For running the PMD, NXP's SoC (board) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
Future Changes/Caveats:
1. VFIO code for fsl-mc bus is different than eal-vfio code for pci bus.
This need to be re-worked to make possible re-use of the existing code.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
---
v8:
* rebased over master (17.02: 35b09d76)
* Removed all drivers/common/* code and moved to drivers/bus/fslmc
* Updated documentation to remove non-open source dependency
* Reduced shared symbols in map files
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (45):
mk/dpaa2: add the crc support to the machine type
bus/fslmc: introducing fsl-mc bus driver
bus/fslmc: add QBMAN driver to bus
bus/fslmc: introduce MC object functions
bus/fslmc: add mc dpio object support
bus/fslmc: add mc dpbp object support
eal/vfio: adding vfio utility functions in map file
bus/fslmc: add vfio support
bus/fslmc: scan for net and sec device
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
bus/fslmc: add debug log support
net/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
net/dpaa2: add mc dpni object support
bus/fslmc: dpio portal driver
bus/fslmc: introduce support for hw mempool object
pool/dpaa2: add DPAA2 hardware offloaded mempool
bus/fslmc: affine dpio to crypto threads
bus/fslmc: define queues for DPAA2 devices
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
bus/fslmc: define hardware annotation area size
net/dpaa2: attach the buffer pool to dpni
bus/fslmc: introduce true and false macros
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
bus/fslmc: define VLAN header length
net/dpaa2: add MTU configuration support
bus/fslmc: add packet FLE definitions
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
bus/fslmc: add physical-virtual address translation helpers
pool/dpaa2: enable physical addressing for pool buffers
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
bus/fslmc: add support for DMA mapping for ARM SMMU
net/dpaa2: enable DMA Mapping during device scanning
bus/fslmc: frame queue based dq storage alloc
net/dpaa2: enable frame queue based dequeuing
Shreyansh Jain (1):
mk: handle intra drivers dependencies for shared build
MAINTAINERS | 8 +
config/common_base | 21 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 27 +-
doc/guides/nics/dpaa2.rst | 614 ++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
drivers/Makefile | 2 +
drivers/bus/Makefile | 38 +
drivers/bus/fslmc/Makefile | 79 ++
drivers/bus/fslmc/fslmc_bus.c | 135 ++
drivers/bus/fslmc/fslmc_logs.h | 76 +
drivers/bus/fslmc/fslmc_vfio.c | 629 ++++++++
drivers/bus/fslmc/fslmc_vfio.h | 82 ++
drivers/bus/fslmc/mc/dpbp.c | 237 ++++
drivers/bus/fslmc/mc/dpio.c | 279 ++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 +++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 ++
drivers/bus/fslmc/mc/mc_sys.c | 114 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 441 ++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 70 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 247 ++++
drivers/bus/fslmc/qbman/include/compat.h | 406 ++++++
drivers/bus/fslmc/qbman/include/fsl_qbman_base.h | 160 +++
drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/bus/fslmc/qbman/qbman_portal.c | 1496 ++++++++++++++++++++
drivers/bus/fslmc/qbman/qbman_portal.h | 277 ++++
drivers/bus/fslmc/qbman/qbman_private.h | 170 +++
drivers/bus/fslmc/qbman/qbman_sys.h | 385 +++++
drivers/bus/fslmc/qbman/qbman_sys_decl.h | 73 +
drivers/bus/fslmc/rte_bus_fslmc_version.map | 49 +
drivers/bus/fslmc/rte_fslmc.h | 148 ++
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 77 +
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 +++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1040 ++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 ++++++
drivers/net/dpaa2/mc/dpni.c | 739 ++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 +++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 ++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 +++++
drivers/net/dpaa2/mc/fsl_net.h | 487 +++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
drivers/pool/Makefile | 40 +
drivers/pool/dpaa2/Makefile | 72 +
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 352 +++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
mk/machine/dpaa2/rte.vars.mk | 5 +-
mk/rte.app.mk | 3 +
mk/rte.lib.mk | 2 +-
60 files changed, 14347 insertions(+), 6 deletions(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
create mode 100644 drivers/bus/fslmc/qbman/include/compat.h
create mode 100644 drivers/bus/fslmc/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_portal.c
create mode 100644 drivers/bus/fslmc/qbman/qbman_portal.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_private.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_sys.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_sys_decl.h
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
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_pool_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 01/46] mk/dpaa2: add the crc support to the machine type
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 02/46] mk: handle intra drivers dependencies for shared build Hemant Agrawal
` (47 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
mk/machine/dpaa2/rte.vars.mk | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mk/machine/dpaa2/rte.vars.mk b/mk/machine/dpaa2/rte.vars.mk
index 8541633..e4735c2 100644
--- a/mk/machine/dpaa2/rte.vars.mk
+++ b/mk/machine/dpaa2/rte.vars.mk
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -53,7 +54,7 @@
# CPU_CFLAGS =
# CPU_LDFLAGS =
# CPU_ASFLAGS =
-MACHINE_CFLAGS += -march=armv8-a
+MACHINE_CFLAGS += -march=armv8-a+crc
ifdef CONFIG_RTE_ARCH_ARM_TUNE
MACHINE_CFLAGS += -mcpu=$(CONFIG_RTE_ARCH_ARM_TUNE)
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 02/46] mk: handle intra drivers dependencies for shared build
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 01/46] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 03/46] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
` (46 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
From: Shreyansh Jain <shreyansh.jain@nxp.com>
Suggested-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
mk/rte.lib.mk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 987553d..d79db80 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -79,7 +79,7 @@ endif
# Translate DEPDIRS-y into LDLIBS
# Ignore (sub)directory dependencies which do not provide an actual library
-_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat
+_IGNORE_DIRS = lib/librte_eal/% lib/librte_compat drivers/%
_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
_LDDIRS = $(subst librte_ether,librte_ethdev,$(_DEPDIRS))
LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 03/46] bus/fslmc: introducing fsl-mc bus driver
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 01/46] mk/dpaa2: add the crc support to the machine type Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 02/46] mk: handle intra drivers dependencies for shared build Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 04/46] bus/fslmc: add QBMAN driver to bus Hemant Agrawal
` (45 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The fslmc bus driver is a rte_bus driver which scans the fsl-mc bus
for NXP DPAA2 SoCs.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 3 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +-
drivers/Makefile | 1 +
drivers/bus/Makefile | 36 +++++++
drivers/bus/fslmc/Makefile | 66 +++++++++++++
drivers/bus/fslmc/fslmc_bus.c | 125 +++++++++++++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 8 ++
drivers/bus/fslmc/rte_fslmc.h | 148 ++++++++++++++++++++++++++++
9 files changed, 399 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/rte_bus_fslmc_version.map
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 5030c1c..0eda467 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -356,6 +356,9 @@ M: Alejandro Lucero <alejandro.lucero@netronome.com>
F: drivers/net/nfp/
F: doc/guides/nics/nfp.rst
+NXP dpaa2
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/bus/fslmc/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/config/common_base b/config/common_base
index aeee13e..e7ab12f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,6 +287,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=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 66df54c..365ae5a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# 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
@@ -40,3 +41,8 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
#
CONFIG_RTE_MAX_LCORE=8
CONFIG_RTE_MAX_NUMA_NODES=1
+
+#
+# Compile NXP DPAA2 FSL-MC Bus
+#
+CONFIG_RTE_LIBRTE_FSLMC_BUS=y
diff --git a/drivers/Makefile b/drivers/Makefile
index 81c03a8..e937449 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -31,6 +31,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
+DIRS-y += bus
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000..60e9764
--- /dev/null
+++ b/drivers/bus/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_FSLMC_BUS) += fslmc
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
new file mode 100644
index 0000000..ad28d8a
--- /dev/null
+++ b/drivers/bus/fslmc/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_bus_fslmc.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+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
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_bus_fslmc_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
new file mode 100644
index 0000000..8a4f519
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -0,0 +1,125 @@
+/*-
+ * 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.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_ethdev.h>
+
+#include "rte_fslmc.h"
+
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+ RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+struct rte_fslmc_bus rte_fslmc_bus;
+
+static int
+rte_fslmc_scan(void)
+{
+ return 0;
+}
+
+static int
+rte_fslmc_match(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
+ return 0;
+
+ return 1;
+}
+
+static int
+rte_fslmc_probe(void)
+{
+ int ret = -1;
+ struct rte_dpaa2_device *dev;
+ struct rte_dpaa2_driver *drv;
+
+ TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
+ TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
+ ret = rte_fslmc_match(drv, dev);
+ if (ret)
+ continue;
+
+ if (!drv->probe)
+ continue;
+
+ ret = drv->probe(drv, dev);
+ if (ret)
+ FSLMC_BUS_LOG(ERR, "Unable to probe.\n");
+ break;
+ }
+ }
+ return ret;
+}
+
+/*register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
+{
+ RTE_VERIFY(driver);
+
+ TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = &rte_fslmc_bus;
+}
+
+/*un-register a fslmc bus based dpaa2 driver */
+void
+rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver)
+{
+ struct rte_fslmc_bus *fslmc_bus;
+
+ fslmc_bus = driver->fslmc_bus;
+
+ TAILQ_REMOVE(&fslmc_bus->driver_list, driver, next);
+ /* Update Bus references */
+ driver->fslmc_bus = NULL;
+}
+
+struct rte_fslmc_bus rte_fslmc_bus = {
+ .bus = {
+ .scan = rte_fslmc_scan,
+ .probe = rte_fslmc_probe,
+ },
+ .device_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.device_list),
+ .driver_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus);
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
new file mode 100644
index 0000000..41c80d9
--- /dev/null
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -0,0 +1,8 @@
+DPDK_17.05 {
+ global:
+
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
new file mode 100644
index 0000000..040ab95
--- /dev/null
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -0,0 +1,148 @@
+/*-
+ * 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 _RTE_FSLMC_H_
+#define _RTE_FSLMC_H_
+
+/**
+ * @file
+ *
+ * RTE FSLMC Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/** Name of FSLMC Bus */
+#define FSLMC_BUS_NAME "FSLMC"
+
+struct rte_dpaa2_driver;
+
+/* DPAA2 Device and Driver lists for FSLMC bus */
+TAILQ_HEAD(rte_fslmc_device_list, rte_dpaa2_device);
+TAILQ_HEAD(rte_fslmc_driver_list, rte_dpaa2_driver);
+
+extern struct rte_fslmc_bus rte_fslmc_bus;
+
+/**
+ * A structure describing a DPAA2 device.
+ */
+struct rte_dpaa2_device {
+ TAILQ_ENTRY(rte_dpaa2_device) next; /**< Next probed DPAA2 device. */
+ struct rte_device device; /**< Inherit core device */
+ union {
+ struct rte_eth_dev *eth_dev; /**< ethernet device */
+ struct rte_cryptodev *cryptodev; /**< Crypto Device */
+ };
+ uint16_t dev_type; /**< Device Type */
+ uint16_t object_id; /**< DPAA2 Object ID */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
+ struct rte_dpaa2_driver *driver; /**< Associated driver */
+};
+
+typedef int (*rte_dpaa2_probe_t)(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev);
+typedef int (*rte_dpaa2_remove_t)(struct rte_dpaa2_device *dpaa2_dev);
+
+/**
+ * A structure describing a DPAA2 driver.
+ */
+struct rte_dpaa2_driver {
+ TAILQ_ENTRY(rte_dpaa2_driver) next; /**< Next in list. */
+ struct rte_driver driver; /**< Inherit core driver. */
+ struct rte_fslmc_bus *fslmc_bus; /**< FSLMC bus reference */
+ uint32_t drv_flags; /**< Flags for controlling device.*/
+ uint16_t drv_type; /**< Driver Type */
+ rte_dpaa2_probe_t probe;
+ rte_dpaa2_remove_t remove;
+};
+
+/*
+ * FSLMC bus
+ */
+struct rte_fslmc_bus {
+ struct rte_bus bus; /**< Generic Bus object */
+ struct rte_fslmc_device_list device_list;
+ /**< FSLMC DPAA2 Device list */
+ struct rte_fslmc_driver_list driver_list;
+ /**< FSLMC DPAA2 Driver list */
+ int device_count;
+ /**< Optional: Count of devices on bus */
+};
+
+/**
+ * Register a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be registered.
+ */
+void rte_fslmc_driver_register(struct rte_dpaa2_driver *driver);
+
+/**
+ * Unregister a DPAA2 driver.
+ *
+ * @param driver
+ * A pointer to a rte_dpaa2_driver structure describing the driver
+ * to be unregistered.
+ */
+void rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver);
+
+/** Helper for DPAA2 device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_DPAA2(nm, dpaa2_drv) \
+RTE_INIT(dpaa2initfn_ ##nm); \
+static void dpaa2initfn_ ##nm(void) \
+{\
+ (dpaa2_drv).driver.name = RTE_STR(nm);\
+ rte_fslmc_driver_register(&dpaa2_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_FSLMC_H_ */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 04/46] bus/fslmc: add QBMAN driver to bus
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (2 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 03/46] bus/fslmc: introducing fsl-mc bus driver Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 05/46] bus/fslmc: introduce MC object functions Hemant Agrawal
` (44 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
QBMAN, is a hardware block which interfaces with the other
accelerating hardware blocks (For e.g., WRIOP) on NXP's DPAA2
SoC for queue, buffer and packet scheduling.
This patch introduces a userspace driver for interfacing with
the QBMAN hw block.
The qbman-portal component provides APIs to do the low level
hardware bit twiddling for operations such as:
-initializing Qman software portals
-building and sending portal commands
-portal interrupt configuration and processing
This same/similar code is used in kernel and compat file is used
to make it working in user space.
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@nxp.com>
Signed-off-by: Roy Pledge <Roy.Pledge@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 4 +
drivers/bus/fslmc/qbman/include/compat.h | 406 ++++++
drivers/bus/fslmc/qbman/include/fsl_qbman_base.h | 160 +++
drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h | 1093 ++++++++++++++
drivers/bus/fslmc/qbman/qbman_portal.c | 1496 ++++++++++++++++++++
drivers/bus/fslmc/qbman/qbman_portal.h | 277 ++++
drivers/bus/fslmc/qbman/qbman_private.h | 170 +++
drivers/bus/fslmc/qbman/qbman_sys.h | 385 +++++
drivers/bus/fslmc/qbman/qbman_sys_decl.h | 73 +
drivers/bus/fslmc/rte_bus_fslmc_version.map | 19 +
10 files changed, 4083 insertions(+)
create mode 100644 drivers/bus/fslmc/qbman/include/compat.h
create mode 100644 drivers/bus/fslmc/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_portal.c
create mode 100644 drivers/bus/fslmc/qbman/qbman_portal.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_private.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_sys.h
create mode 100644 drivers/bus/fslmc/qbman/qbman_sys_decl.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index ad28d8a..7368ce0 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ endif
CFLAGS += "-Wno-strict-aliasing"
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -58,6 +59,9 @@ EXPORT_MAP := rte_bus_fslmc_version.map
# library version
LIBABIVER := 1
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ qbman/qbman_portal.c
+
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
diff --git a/drivers/bus/fslmc/qbman/include/compat.h b/drivers/bus/fslmc/qbman/include/compat.h
new file mode 100644
index 0000000..28d7952
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/include/compat.h
@@ -0,0 +1,406 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2008-2016 Freescale Semiconductor, Inc.
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 HEADER_COMPAT_H
+#define HEADER_COMPAT_H
+
+#include <sched.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <net/ethernet.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <assert.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <error.h>
+#include <rte_atomic.h>
+
+/* The following definitions are primarily to allow the single-source driver
+ * interfaces to be included by arbitrary program code. Ie. for interfaces that
+ * are also available in kernel-space, these definitions provide compatibility
+ * with certain attributes and types used in those interfaces.
+ */
+
+/* Required compiler attributes */
+#define __user
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+#undef container_of
+#define container_of(ptr, type, member) ({ \
+ typeof(((type *)0)->member)(*__mptr) = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#ifdef ARRAY_SIZE
+#undef ARRAY_SIZE
+#endif
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/* Required types */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uint64_t dma_addr_t;
+typedef cpu_set_t cpumask_t;
+typedef u32 compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+/* I/O operations */
+static inline u32 in_be32(volatile void *__p)
+{
+ volatile u32 *p = __p;
+ return *p;
+}
+
+static inline void out_be32(volatile void *__p, u32 val)
+{
+ volatile u32 *p = __p;
+ *p = val;
+}
+
+/* Debugging */
+#define prflush(fmt, args...) \
+ do { \
+ printf(fmt, ##args); \
+ fflush(stdout); \
+ } while (0)
+#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args)
+#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args)
+#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args)
+#define pr_info(fmt, args...) prflush(fmt, ##args)
+
+#ifdef pr_debug
+#undef pr_debug
+#endif
+#define pr_debug(fmt, args...) {}
+#define might_sleep_if(c) {}
+#define msleep(x) {}
+#define WARN_ON(c, str) \
+do { \
+ static int warned_##__LINE__; \
+ if ((c) && !warned_##__LINE__) { \
+ pr_warn("%s\n", str); \
+ pr_warn("(%s:%d)\n", __FILE__, __LINE__); \
+ warned_##__LINE__ = 1; \
+ } \
+} while (0)
+#define QBMAN_BUG_ON(c) WARN_ON(c, "BUG")
+
+#define ALIGN(x, a) (((x) + ((typeof(x))(a) - 1)) & ~((typeof(x))(a) - 1))
+
+/****************/
+/* Linked-lists */
+/****************/
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_HEAD(n) \
+struct list_head n = { \
+ .prev = &n, \
+ .next = &n \
+}
+
+#define INIT_LIST_HEAD(p) \
+do { \
+ struct list_head *__p298 = (p); \
+ __p298->next = __p298; \
+ __p298->prev = __p298->next; \
+} while (0)
+#define list_entry(node, type, member) \
+ (type *)((void *)node - offsetof(type, member))
+#define list_empty(p) \
+({ \
+ const struct list_head *__p298 = (p); \
+ ((__p298->next == __p298) && (__p298->prev == __p298)); \
+})
+#define list_add(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->next = __l298->next; \
+ __p298->prev = __l298; \
+ __l298->next->prev = __p298; \
+ __l298->next = __p298; \
+} while (0)
+#define list_add_tail(p, l) \
+do { \
+ struct list_head *__p298 = (p); \
+ struct list_head *__l298 = (l); \
+ __p298->prev = __l298->prev; \
+ __p298->next = __l298; \
+ __l298->prev->next = __p298; \
+ __l298->prev = __p298; \
+} while (0)
+#define list_for_each(i, l) \
+ for (i = (l)->next; i != (l); i = i->next)
+#define list_for_each_safe(i, j, l) \
+ for (i = (l)->next, j = i->next; i != (l); \
+ i = j, j = i->next)
+#define list_for_each_entry(i, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \
+ i = list_entry(i->name.next, typeof(*i), name))
+#define list_for_each_entry_safe(i, j, l, name) \
+ for (i = list_entry((l)->next, typeof(*i), name), \
+ j = list_entry(i->name.next, typeof(*j), name); \
+ &i->name != (l); \
+ i = j, j = list_entry(j->name.next, typeof(*j), name))
+#define list_del(i) \
+do { \
+ (i)->next->prev = (i)->prev; \
+ (i)->prev->next = (i)->next; \
+} while (0)
+
+/* Other miscellaneous interfaces our APIs depend on; */
+
+#define lower_32_bits(x) ((u32)(x))
+#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16))
+
+/* Compiler/type stuff */
+typedef unsigned int gfp_t;
+typedef uint32_t phandle;
+
+#define __iomem
+#define EINTR 4
+#define ENODEV 19
+#define GFP_KERNEL 0
+#define __raw_readb(p) (*(const volatile unsigned char *)(p))
+#define __raw_readl(p) (*(const volatile unsigned int *)(p))
+#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); }
+
+/* memcpy() stuff - when you know alignments in advance */
+#ifdef CONFIG_TRY_BETTER_MEMCPY
+static inline void copy_words(void *dest, const void *src, size_t sz)
+{
+ u32 *__dest = dest;
+ const u32 *__src = src;
+ size_t __sz = sz >> 2;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x3);
+ QBMAN_BUG_ON((unsigned long)src & 0x3);
+ QBMAN_BUG_ON(sz & 0x3);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_shorts(void *dest, const void *src, size_t sz)
+{
+ u16 *__dest = dest;
+ const u16 *__src = src;
+ size_t __sz = sz >> 1;
+
+ QBMAN_BUG_ON((unsigned long)dest & 0x1);
+ QBMAN_BUG_ON((unsigned long)src & 0x1);
+ QBMAN_BUG_ON(sz & 0x1);
+ while (__sz--)
+ *(__dest++) = *(__src++);
+}
+
+static inline void copy_bytes(void *dest, const void *src, size_t sz)
+{
+ u8 *__dest = dest;
+ const u8 *__src = src;
+
+ while (sz--)
+ *(__dest++) = *(__src++);
+}
+#else
+#define copy_words memcpy
+#define copy_shorts memcpy
+#define copy_bytes memcpy
+#endif
+
+/* Completion stuff */
+#define DECLARE_COMPLETION(n) int n = 0
+#define complete(n) { *n = 1; }
+#define wait_for_completion(n) \
+do { \
+ while (!*n) { \
+ bman_poll(); \
+ qman_poll(); \
+ } \
+ *n = 0; \
+} while (0)
+
+/* Allocator stuff */
+#define kmalloc(sz, t) malloc(sz)
+#define vmalloc(sz) malloc(sz)
+#define kfree(p) { if (p) free(p); }
+static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused)
+{
+ void *ptr = malloc(sz);
+
+ if (ptr)
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
+{
+ void *p;
+
+ if (posix_memalign(&p, 4096, 4096))
+ return 0;
+ memset(p, 0, 4096);
+ return (unsigned long)p;
+}
+
+static inline void free_page(unsigned long p)
+{
+ free((void *)p);
+}
+
+/* Bitfield stuff. */
+#define BITS_PER_ULONG (sizeof(unsigned long) << 3)
+#define SHIFT_PER_ULONG (((1 << 5) == BITS_PER_ULONG) ? 5 : 6)
+#define BITS_MASK(idx) ((unsigned long)1 << ((idx) & (BITS_PER_ULONG - 1)))
+#define BITS_IDX(idx) ((idx) >> SHIFT_PER_ULONG)
+static inline unsigned long test_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ return *p & mask;
+}
+
+static inline int test_bit(int idx, volatile unsigned long *bits)
+{
+ return test_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void set_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p |= mask;
+}
+
+static inline void set_bit(int idx, volatile unsigned long *bits)
+{
+ set_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
+{
+ *p &= ~mask;
+}
+
+static inline void clear_bit(int idx, volatile unsigned long *bits)
+{
+ clear_bits(BITS_MASK(idx), bits + BITS_IDX(idx));
+}
+
+static inline unsigned long test_and_set_bits(unsigned long mask,
+ volatile unsigned long *p)
+{
+ unsigned long ret = test_bits(mask, p);
+
+ set_bits(mask, p);
+ return ret;
+}
+
+static inline int test_and_set_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ set_bit(idx, bits);
+ return ret;
+}
+
+static inline int test_and_clear_bit(int idx, volatile unsigned long *bits)
+{
+ int ret = test_bit(idx, bits);
+
+ clear_bit(idx, bits);
+ return ret;
+}
+
+static inline int find_next_zero_bit(unsigned long *bits, int limit, int idx)
+{
+ while ((++idx < limit) && test_bit(idx, bits))
+ ;
+ return idx;
+}
+
+static inline int find_first_zero_bit(unsigned long *bits, int limit)
+{
+ int idx = 0;
+
+ while (test_bit(idx, bits) && (++idx < limit))
+ ;
+ return idx;
+}
+
+static inline u64 div64_u64(u64 n, u64 d)
+{
+ return n / d;
+}
+
+#define atomic_t rte_atomic32_t
+#define atomic_read(v) rte_atomic32_read(v)
+#define atomic_set(v, i) rte_atomic32_set(v, i)
+
+#define atomic_inc(v) rte_atomic32_add(v, 1)
+#define atomic_dec(v) rte_atomic32_sub(v, 1)
+
+#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v)
+#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v)
+
+#define atomic_inc_return(v) rte_atomic32_add_return(v, 1)
+#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1)
+#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
+
+#endif /* HEADER_COMPAT_H */
diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h
new file mode 100644
index 0000000..ee4b772
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h
@@ -0,0 +1,160 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+typedef uint64_t dma_addr_t;
+
+/**
+ * DOC: QBMan basic structures
+ *
+ * The QBMan block descriptor, software portal descriptor and Frame descriptor
+ * are defined here.
+ *
+ */
+
+#define QMAN_REV_4000 0x04000000
+#define QMAN_REV_4100 0x04010000
+#define QMAN_REV_4101 0x04010001
+
+/**
+ * struct qbman_block_desc - qbman block descriptor structure
+ * @ccsr_reg_bar: CCSR register map.
+ * @irq_rerr: Recoverable error interrupt line.
+ * @irq_nrerr: Non-recoverable error interrupt line
+ *
+ * Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to.
+ */
+struct qbman_block_desc {
+ void *ccsr_reg_bar;
+ int irq_rerr;
+ int irq_nrerr;
+};
+
+enum qbman_eqcr_mode {
+ qman_eqcr_vb_ring = 2, /* Valid bit, with eqcr in ring mode */
+ qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */
+};
+
+/**
+ * struct qbman_swp_desc - qbman software portal descriptor structure
+ * @block: The QBMan instance.
+ * @cena_bar: Cache-enabled portal register map.
+ * @cinh_bar: Cache-inhibited portal register map.
+ * @irq: -1 if unused (or unassigned)
+ * @idx: SWPs within a QBMan are indexed. -1 if opaque to the user.
+ * @qman_version: the qman version.
+ * @eqcr_mode: Select the eqcr mode, currently only valid bit ring mode and
+ * valid bit array mode are supported.
+ *
+ * Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "MC bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering.
+ */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block;
+ uint8_t *cena_bar;
+ uint8_t *cinh_bar;
+ int irq;
+ int idx;
+ uint32_t qman_version;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/**
+ * struct qbman_fd - basci structure for qbman frame descriptor
+ * @words: for easier/faster copying the whole FD structure.
+ * @addr_lo: the lower 32 bits of the address in FD.
+ * @addr_hi: the upper 32 bits of the address in FD.
+ * @len: the length field in FD.
+ * @bpid_offset: represent the bpid and offset fields in FD. offset in
+ * the MS 16 bits, BPID in the LS 16 bits.
+ * @frc: frame context
+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
+ * @flc_lo: the lower 32bit of flow context.
+ * @flc_hi: the upper 32bits of flow context.
+ *
+ * Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ uint32_t bpid_offset;
+ uint32_t frc;
+ uint32_t ctrl;
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h
new file mode 100644
index 0000000..7731772
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h
@@ -0,0 +1,1093 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl_qbman_base.h>
+
+/**
+ * DOC - QBMan portal APIs to implement the following functions:
+ * - Initialize and destroy Software portal object.
+ * - Read and write Software portal interrupt registers.
+ * - Enqueue, including setting the enqueue descriptor, and issuing enqueue
+ * command etc.
+ * - Dequeue, including setting the dequeue descriptor, issuing dequeue command,
+ * parsing the dequeue response in DQRR and memeory, parsing the state change
+ * notifications etc.
+ * - Release, including setting the release descriptor, and issuing the buffer
+ * release command.
+ * - Acquire, acquire the buffer from the given buffer pool.
+ * - FQ management.
+ * - Channel management, enable/disable CDAN with or without context.
+ */
+
+/**
+ * qbman_swp_init() - Create a functional object representing the given
+ * QBMan portal descriptor.
+ * @d: the given qbman swp descriptor
+ *
+ * Return qbman_swp portal object for success, NULL if the object cannot
+ * be created.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
+
+/**
+ * qbman_swp_finish() - Create and destroy a functional object representing
+ * the given QBMan portal descriptor.
+ * @p: the qbman_swp object to be destroyed.
+ *
+ */
+void qbman_swp_finish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_get_desc() - Get the descriptor of the given portal object.
+ * @p: the given portal object.
+ *
+ * Return the descriptor for this portal.
+ */
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p);
+
+ /**************/
+ /* Interrupts */
+ /**************/
+
+/* EQCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_EQRI ((uint32_t)0x00000001)
+/* Enqueue command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_EQDI ((uint32_t)0x00000002)
+/* DQRR non-empty interrupt */
+#define QBMAN_SWP_INTERRUPT_DQRI ((uint32_t)0x00000004)
+/* RCR ring interrupt */
+#define QBMAN_SWP_INTERRUPT_RCRI ((uint32_t)0x00000008)
+/* Release command dispatched interrupt */
+#define QBMAN_SWP_INTERRUPT_RCDI ((uint32_t)0x00000010)
+/* Volatile dequeue command interrupt */
+#define QBMAN_SWP_INTERRUPT_VDCI ((uint32_t)0x00000020)
+
+/**
+ * qbman_swp_interrupt_get_vanish() - Get the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISDR register.
+ */
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_vanish() - Set the data in software portal
+ * interrupt status disable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IDSR register.
+ */
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_read_status() - Get the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_ISR register.
+ */
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_clear_status() - Set the data in software portal
+ * interrupt status register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_ISR register.
+ */
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_trigger() - Get the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IER register.
+ */
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_trigger() - Set the data in software portal
+ * interrupt enable register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IER register.
+ */
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask);
+
+/**
+ * qbman_swp_interrupt_get_inhibit() - Get the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ *
+ * Return the settings in SWP_IIR register.
+ */
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
+
+/**
+ * qbman_swp_interrupt_set_inhibit() - Set the data in software portal
+ * interrupt inhibit register.
+ * @p: the given software portal object.
+ * @mask: The value to set in SWP_IIR register.
+ */
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/**
+ * struct qbman_result - structure for qbman dequeue response and/or
+ * notification.
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * possible qbman dequeue result.
+ */
+struct qbman_result {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* TODO:
+ *A DQRI interrupt can be generated when there are dequeue results on the
+ * portal's DQRR (this mechanism does not deal with "pull" dequeues to
+ * user-supplied 'storage' addresses). There are two parameters to this
+ * interrupt source, one is a threshold and the other is a timeout. The
+ * interrupt will fire if either the fill-level of the ring exceeds 'thresh', or
+ * if the ring has been non-empty for been longer than 'timeout' nanoseconds.
+ * For timeout, an approximation to the desired nanosecond-granularity value is
+ * made, so there are get and set APIs to allow the user to see what actual
+ * timeout is set (compared to the timeout that was requested).
+ */
+int qbman_swp_dequeue_thresh(struct qbman_swp *s, unsigned int thresh);
+int qbman_swp_dequeue_set_timeout(struct qbman_swp *s, unsigned int timeout);
+int qbman_swp_dequeue_get_timeout(struct qbman_swp *s, unsigned int *timeout);
+
+/* ------------------- */
+/* Push-mode dequeuing */
+/* ------------------- */
+
+/* The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+
+/**
+ * qbman_swp_push_get() - Get the push dequeue setup.
+ * @s: the software portal object.
+ * @channel_idx: the channel index to query.
+ * @enabled: returned boolean to show whether the push dequeue is enabled for
+ * the given channel.
+ */
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled);
+
+/**
+ * qbman_swp_push_set() - Enable or disable push dequeue.
+ * @s: the software portal object.
+ * @channel_idx: the channel index..
+ * @enable: enable or disable push dequeue.
+ *
+ * The user of a portal can enable and disable push-mode dequeuing of up to 16
+ * channels independently. It does not specify this toggling by channel IDs, but
+ * rather by specifying the index (from 0 to 15) that has been mapped to the
+ * desired channel.
+ */
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable);
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+/**
+ * struct qbman_pull_desc - the structure for pull dequeue descriptor
+ * @dont_manipulate_directly: the 6 32bit data to represent the whole
+ * possible settings for pull dequeue descriptor.
+ */
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+enum qbman_pull_type_e {
+ /* dequeue with priority precedence, respect intra-class scheduling */
+ qbman_pull_type_prio = 1,
+ /* dequeue with active FQ precedence, respect ICS */
+ qbman_pull_type_active,
+ /* dequeue with active FQ precedence, no ICS */
+ qbman_pull_type_active_noics
+};
+
+/**
+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the pull dequeue descriptor to be cleared.
+ */
+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
+
+/**
+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
+ * @d: the pull dequeue descriptor to be set.
+ * @storage: the pointer of the memory to store the dequeue result.
+ * @storage_phys: the physical address of the storage memory.
+ * @stash: to indicate whether write allocate is enabled.
+ *
+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute.
+ */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/**
+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued.
+ * @d: the pull dequeue descriptor to be set.
+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive.
+ */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,
+ uint8_t numframes);
+/**
+ * qbman_pull_desc_set_token() - Set dequeue token for pull command
+ * @d: the dequeue descriptor
+ * @token: the token to be set
+ *
+ * token is the value that shows up in the dequeue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing a dequeue, and use any non-zero 'token' value
+ */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+/**
+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues.
+ * @fqid: the frame queue index of the given FQ.
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid);
+
+/**
+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues.
+ * @wqid: composed of channel id and wqid within the channel.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct);
+
+/* qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
+ * dequeues.
+ * @chid: the channel id to be dequeued.
+ * @dct: the dequeue command type.
+ */
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct);
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object.
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls.
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry.
+ * @s: the software portal object.
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *p);
+
+/**
+ * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
+ * qbman_swp_dqrr_next().
+ * @s: the software portal object.
+ * @dq: the DQRR entry to be consumed.
+ */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct qbman_result *dq);
+
+/**
+ * qbman_get_dqrr_idx() - Get dqrr index from the given dqrr
+ * @dqrr: the given dqrr object.
+ *
+ * Return dqrr index.
+ */
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr);
+
+/**
+ * qbman_get_dqrr_from_idx() - Use index to get the dqrr entry from the
+ * given portal
+ * @s: the given portal.
+ * @idx: the dqrr index.
+ *
+ * Return dqrr entry object.
+ */
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/**
+ * qbman_result_has_new_result() - Check and get the dequeue response from the
+ * dq storage memory set in pull dequeue command
+ * @s: the software portal object.
+ * @dq: the dequeue result read from the memory.
+ *
+ * Only used for user-provided storage of dequeue results, not DQRR. For
+ * efficiency purposes, the driver will perform any required endianness
+ * conversion to ensure that the user's dequeue result storage is in host-endian
+ * format (whether or not that is the same as the little-endian format that
+ * hardware DMA'd to the user's storage). As such, once the user has called
+ * qbman_result_has_new_result() and been returned a valid dequeue result,
+ * they should not call it again on the same memory location (except of course
+ * if another dequeue command has been executed to produce a new result to that
+ * location).
+ *
+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
+ * dequeue result.
+ */
+int qbman_result_has_new_result(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/**
+ * qbman_result_is_DQ() - check the dequeue result is a dequeue response or not
+ * @dq: the dequeue result to be checked.
+ *
+ * DQRR entries may contain non-dequeue results, ie. notifications
+ */
+int qbman_result_is_DQ(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
+ * @dq: the dequeue result to be checked.
+ *
+ * All the non-dequeue results (FQDAN/CDAN/CSCN/...) are "state change
+ * notifications" of one type or another. Some APIs apply to all of them, of the
+ * form qbman_result_SCN_***().
+ */
+static inline int qbman_result_is_SCN(const struct qbman_result *dq)
+{
+ return !qbman_result_is_DQ(dq);
+}
+
+/* Recognise different notification types, only required if the user allows for
+ * these to occur, and cares about them when they do.
+ */
+
+/**
+ * qbman_result_is_FQDAN() - Check for FQ Data Availability
+ * @dq: the qbman_result object.
+ *
+ * Return 1 if this is FQDAN.
+ */
+int qbman_result_is_FQDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CDAN() - Check for Channel Data Availability
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CDAN.
+ */
+int qbman_result_is_CDAN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CSCN() - Check for Congestion State Change
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CSCN.
+ */
+int qbman_result_is_CSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_BPSCN() - Check for Buffer Pool State Change.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is BPSCN.
+ */
+int qbman_result_is_BPSCN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_CGCU() - Check for Congestion Group Count Update.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is CGCU.
+ */
+int qbman_result_is_CGCU(const struct qbman_result *dq);
+
+/* Frame queue state change notifications; (FQDAN in theory counts too as it
+ * leaves a FQ parked, but it is primarily a data availability notification)
+ */
+
+/**
+ * qbman_result_is_FQRN() - Check for FQ Retirement Notification.
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRN.
+ */
+int qbman_result_is_FQRN(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQRNI() - Check for FQ Retirement Immediate
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQRNI.
+ */
+int qbman_result_is_FQRNI(const struct qbman_result *dq);
+
+/**
+ * qbman_result_is_FQPN() - Check for FQ Park Notification
+ * @dq: the qbman_result object to check.
+ *
+ * Return 1 if this is FQPN.
+ */
+int qbman_result_is_FQPN(const struct qbman_result *dq);
+
+/* Parsing frame dequeue results (qbman_result_is_DQ() must be TRUE)
+ */
+/* FQ empty */
+#define QBMAN_DQ_STAT_FQEMPTY 0x80
+/* FQ held active */
+#define QBMAN_DQ_STAT_HELDACTIVE 0x40
+/* FQ force eligible */
+#define QBMAN_DQ_STAT_FORCEELIGIBLE 0x20
+/* Valid frame */
+#define QBMAN_DQ_STAT_VALIDFRAME 0x10
+/* FQ ODP enable */
+#define QBMAN_DQ_STAT_ODPVALID 0x04
+/* Volatile dequeue */
+#define QBMAN_DQ_STAT_VOLATILE 0x02
+/* volatile dequeue command is expired */
+#define QBMAN_DQ_STAT_EXPIRED 0x01
+
+/**
+ * qbman_result_DQ_flags() - Get the STAT field of dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the state field.
+ */
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_is_pull() - Check whether the dq response is from a pull
+ * command.
+ * @dq: the dequeue result.
+ *
+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
+ */
+static inline int qbman_result_DQ_is_pull(const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_VOLATILE);
+}
+
+/**
+ * qbman_result_DQ_is_pull_complete() - Check whether the pull command is
+ * completed.
+ * @dq: the dequeue result.
+ *
+ * Return boolean.
+ */
+static inline int qbman_result_DQ_is_pull_complete(
+ const struct qbman_result *dq)
+{
+ return (int)(qbman_result_DQ_flags(dq) & QBMAN_DQ_STAT_EXPIRED);
+}
+
+/**
+ * qbman_result_DQ_seqnum() - Get the seqnum field in dequeue response
+ * seqnum is valid only if VALIDFRAME flag is TRUE
+ * @dq: the dequeue result.
+ *
+ * Return seqnum.
+ */
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_odpid() - Get the seqnum field in dequeue response
+ * odpid is valid only if ODPVAILD flag is TRUE.
+ * @dq: the dequeue result.
+ *
+ * Return odpid.
+ */
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqid() - Get the fqid in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return fqid.
+ */
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_byte_count() - Get the byte count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the byte count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_frame_count - Get the frame count in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame count remaining in the FQ.
+ */
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fqd_ctx() - Get the frame queue context in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame queue context.
+ */
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq);
+
+/**
+ * qbman_result_DQ_fd() - Get the frame descriptor in dequeue response
+ * @dq: the dequeue result.
+ *
+ * Return the frame descriptor.
+ */
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq);
+
+/* State-change notifications (FQDAN/CDAN/CSCN/...). */
+
+/**
+ * qbman_result_SCN_state() - Get the state field in State-change notification
+ * @scn: the state change notification.
+ *
+ * Return the state in the notifiation.
+ */
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid() - Get the resource id from the notification
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_ctx() - get the context from the notification
+ * @scn: the state change notification.
+ *
+ * Return the context.
+ */
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_state_in_mem() - Get the state in notification written
+ * in memory
+ * @scn: the state change notification.
+ *
+ * Return the state.
+ */
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn);
+
+/**
+ * qbman_result_SCN_rid_in_mem() - Get the resource id in notification written
+ * in memory.
+ * @scn: the state change notification.
+ *
+ * Return the resource id.
+ */
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn);
+
+/* Type-specific "resource IDs". Mainly for illustration purposes, though it
+ * also gives the appropriate type widths.
+ */
+/* Get the FQID from the FQDAN */
+#define qbman_result_FQDAN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRN */
+#define qbman_result_FQRN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQRNI */
+#define qbman_result_FQRNI_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the FQID from the FQPN */
+#define qbman_result_FQPN_fqid(dq) qbman_result_SCN_rid(dq)
+/* Get the channel ID from the CDAN */
+#define qbman_result_CDAN_cid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+/* Get the CGID from the CSCN */
+#define qbman_result_CSCN_cgid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
+
+/**
+ * qbman_result_bpscn_bpid() - Get the bpid from BPSCN
+ * @scn: the state change notification.
+ *
+ * Return the buffer pool id.
+ */
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_has_free_bufs() - Check whether there are free
+ * buffers in the pool from BPSCN.
+ * @scn: the state change notification.
+ *
+ * Return the number of free buffers.
+ */
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_depleted() - Check BPSCN to see whether the
+ * buffer pool is depleted.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool depletion.
+ */
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_is_surplus() - Check BPSCN to see whether the buffer
+ * pool is surplus or not.
+ * @scn: the state change notification.
+ *
+ * Return the status of buffer pool surplus.
+ */
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn);
+
+/**
+ * qbman_result_bpscn_ctx() - Get the BPSCN CTX from BPSCN message
+ * @scn: the state change notification.
+ *
+ * Return the BPSCN context.
+ */
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn);
+
+/* Parsing CGCU */
+/**
+ * qbman_result_cgcu_cgid() - Check CGCU resouce id, i.e. cgid
+ * @scn: the state change notification.
+ *
+ * Return the CGCU resource id.
+ */
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn);
+
+/**
+ * qbman_result_cgcu_icnt() - Get the I_CNT from CGCU
+ * @scn: the state change notification.
+ *
+ * Return instantaneous count in the CGCU notification.
+ */
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+/**
+ * struct qbman_eq_desc - structure of enqueue descriptor
+ * @dont_manipulate_directly: the 8 32bit data to represent the whole
+ * possible qbman enqueue setting in enqueue descriptor.
+ */
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+/**
+ * struct qbman_eq_response - structure of enqueue response
+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
+ * enqueue response.
+ */
+struct qbman_eq_response {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/**
+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the given enqueue descriptor.
+ */
+void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+
+/**
+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+/**
+ * qbman_eq_desc_set_orp() - Set order-resotration in the enqueue descriptor
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ * @incomplete: indiates whether this is the last fragments using the same
+ * sequeue number.
+ */
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete);
+
+/**
+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+
+/**
+ * qbman_eq_desc_set_orp_nesn() - advance NESN (Next Expected Sequence Number)
+ * without any enqueue
+ * @d: the enqueue descriptor.
+ * @opr_id: the order point record id.
+ * @seqnum: the order restoration sequence number.
+ */
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum);
+/**
+ * qbman_eq_desc_set_response() - Set the enqueue response info.
+ * @d: the enqueue descriptor
+ * @storage_phys: the physical address of the enqueue response in memory.
+ * @stash: indicate that the write allocation enabled or not.
+ *
+ * In the case where an enqueue response is DMA'd, this determines where that
+ * response should go. (The physical/DMA address is given for hardware's
+ * benefit, but software should interpret it as a "struct qbman_eq_response"
+ * data structure.) 'stash' controls whether or not the write to main-memory
+ * expresses a cache-warming attribute.
+ */
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash);
+
+/**
+ * qbman_eq_desc_set_token() - Set token for the enqueue command
+ * @d: the enqueue descriptor
+ * @token: the token to be set.
+ *
+ * token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value.
+ */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token);
+
+/**
+ * Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+/**
+ * qbman_eq_desc_set_fq() - Set Frame Queue id for the enqueue command
+ * @d: the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued.
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid);
+
+/**
+ * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command.
+ * @d: the enqueue descriptor
+ * @qdid: the id of the queuing destination to be enqueued.
+ * @qd_bin: the queuing destination bin
+ * @qd_prio: the queuing destination priority.
+ */
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/**
+ * qbman_eq_desc_set_eqdi() - enable/disable EQDI interrupt
+ * @d: the enqueue descriptor
+ * @enable: boolean to enable/disable EQDI
+ *
+ * Determines whether or not the portal's EQDI interrupt source should be
+ * asserted after the enqueue command is completed.
+ */
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable);
+
+/**
+ * qbman_eq_desc_set_dca() - Set DCA mode in the enqueue command.
+ * @d: the enqueue descriptor.
+ * @enable: enabled/disable DCA mode.
+ * @dqrr_idx: DCAP_CI, the DCAP consumer index.
+ * @park: determine the whether park the FQ or not
+ *
+ * Determines whether or not a portal DQRR entry should be consumed once the
+ * enqueue command is completed. (And if so, and the DQRR entry corresponds to a
+ * held-active (order-preserving) FQ, whether the FQ should be parked instead of
+ * being rescheduled.)
+ */
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park);
+
+/**
+ * qbman_swp_enqueue() - Issue an enqueue command.
+ * @s: the software portal used for enqueue.
+ * @d: the enqueue descriptor.
+ * @fd: the frame descriptor to be enqueued.
+ *
+ * Please note that 'fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".
+ *
+ * Return 0 for a successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd);
+
+/* TODO:
+ * qbman_swp_enqueue_thresh() - Set threshold for EQRI interrupt.
+ * @s: the software portal.
+ * @thresh: the threshold to trigger the EQRI interrupt.
+ *
+ * An EQRI interrupt can be generated when the fill-level of EQCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_enqueue_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+/**
+ * struct qbman_release_desc - The structure for buffer release descriptor
+ * @dont_manipulate_directly: the 32bit data to represent the whole
+ * possible settings of qbman release descriptor.
+ */
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/**
+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
+ * default/starting state.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_clear(struct qbman_release_desc *d);
+
+/**
+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid);
+
+/**
+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
+ * interrupt source should be asserted after the release command is completed.
+ * @d: the qbman release descriptor.
+ */
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+
+/**
+ * qbman_swp_release() - Issue a buffer release command.
+ * @s: the software portal object.
+ * @d: the release descriptor.
+ * @buffers: a pointer pointing to the buffer address to be released.
+ * @num_buffers: number of buffers to be released, must be less than 8.
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+/* TODO:
+ * qbman_swp_release_thresh() - Set threshold for RCRI interrupt
+ * @s: the software portal.
+ * @thresh: the threshold.
+ * An RCRI interrupt can be generated when the fill-level of RCR falls below
+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
+ */
+int qbman_swp_release_thresh(struct qbman_swp *s, unsigned int thresh);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+/**
+ * qbman_swp_acquire() - Issue a buffer acquire command.
+ * @s: the software portal object.
+ * @bpid: the buffer pool index.
+ * @buffers: a pointer pointing to the acquired buffer address|es.
+ * @num_buffers: number of buffers to be acquired, must be less than 8.
+ *
+ * Return 0 for success, or negative error code if the acquire command
+ * fails.
+ */
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+
+ /*****************/
+ /* FQ management */
+ /*****************/
+/**
+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be scheduled.
+ *
+ * There are a couple of different ways that a FQ can end up parked state,
+ * This schedules it.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue to be forced.
+ *
+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
+ * and thus be available for selection by any channel-dequeuing behaviour (push
+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
+ * empty at the time this happens, the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid);
+
+/**
+ * These functions change the FQ flow-control stuff between XON/XOFF. (The
+ * default is XON.) This setting doesn't affect enqueues to the FQ, just
+ * dequeues. XOFF FQs will remain in the tenatively-scheduled state, even when
+ * non-empty, meaning they won't be selected for scheduled dequeuing. If a FQ is
+ * changed to XOFF after it had already become truly-scheduled to a channel, and
+ * a pull dequeue of that channel occurs that selects that FQ for dequeuing,
+ * then the resulting dq_entry will have no FD. (qbman_result_DQ_fd() will
+ * return NULL.)
+ */
+/**
+ * qbman_swp_fq_xon() - XON the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid);
+/**
+ * qbman_swp_fq_xoff() - XOFF the frame queue.
+ * @s: the software portal object.
+ * @fqid: the index of frame queue.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid);
+
+ /**********************/
+ /* Channel management */
+ /**********************/
+
+/**
+ * If the user has been allocated a channel object that is going to generate
+ * CDANs to another channel, then these functions will be necessary.
+ * CDAN-enabled channels only generate a single CDAN notification, after which
+ * it they need to be reenabled before they'll generate another. (The idea is
+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
+ * reenable step.) Each function generates a distinct command to hardware, so a
+ * combination function is provided if the user wishes to modify the "context"
+ * (which shows up in each CDAN message) each time they reenable, as a single
+ * command to hardware.
+ */
+
+/**
+ * qbman_swp_CDAN_set_context() - Set CDAN context
+ * @s: the software portal object.
+ * @channelid: the channel index.
+ * @ctx: the context to be set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+
+/**
+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_disable() - disable CDAN for the channel.
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid);
+
+/**
+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
+ * @s: the software portal object.
+ * @channelid: the index of the channel to generate CDAN.
+ * @ctx: the context set in CDAN.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx);
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ uint8_t burst_index);
+int qbman_swp_flush_ring(struct qbman_swp *s);
+void qbman_sync(void);
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send);
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq);
+
+int qbman_get_version(void);
+#endif /* !_FSL_QBMAN_PORTAL_H */
diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c
new file mode 100644
index 0000000..5d407cc
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/qbman_portal.c
@@ -0,0 +1,1496 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQCR_PI 0x800
+#define QBMAN_CINH_SWP_EQCR_CI 0x840
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DQPI 0xa00
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+#define QBMAN_CINH_SWP_ISR 0xe00
+#define QBMAN_CINH_SWP_IER 0xe40
+#define QBMAN_CINH_SWP_ISDR 0xe80
+#define QBMAN_CINH_SWP_IIR 0xec0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+#define QBMAN_CENA_SWP_EQCR_CI 0x840
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
+
+/* QBMan FQ management command codes */
+#define QBMAN_FQ_SCHEDULE 0x48
+#define QBMAN_FQ_FORCE 0x49
+#define QBMAN_FQ_XON 0x4d
+#define QBMAN_FQ_XOFF 0x4e
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init()
+ */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_eq_dca_idx;
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+struct qb_attr_code code_sdqcr_dqsrc = QB_CODE(0, 0, 16);
+
+/* We need to keep track of which SWP triggered a pull command
+ * so keep an array of portal IDs and use the token field to
+ * be able to find the proper portal
+ */
+#define MAX_QBMAN_PORTALS 35
+static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];
+
+uint32_t qman_version;
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has.
+ *
+ * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
+ * valid-bits, so we need to support a workaround where we don't trust
+ * valid-bits when detecting new entries until any stale ring entries have been
+ * overwritten at least once. The idea is that we read PI for the first few
+ * entries, then switch to valid-bit after that. The trick is to clear the
+ * bug-work-around boolean once the PI wraps around the ring for the first time.
+ *
+ * Note: this still carries a slight additional cost once the decrementer hits
+ * zero.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ uint32_t eqcr_pi;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = *d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
+ atomic_set(&p->vdq.busy, 1);
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ qman_version = p->desc.qman_version;
+ if ((qman_version & 0xFFFF0000) < QMAN_REV_4100) {
+ p->dqrr.dqrr_size = 4;
+ p->dqrr.reset_bug = 1;
+ /* Set size of DQRR to 4, encoded in 2 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 2);
+ } else {
+ p->dqrr.dqrr_size = 8;
+ p->dqrr.reset_bug = 0;
+ /* Set size of DQRR to 8, encoded in 3 bits */
+ code_eq_dca_idx = (struct qb_attr_code)QB_CODE(0, 8, 3);
+ }
+
+ ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
+ if (ret) {
+ kfree(p);
+ pr_err("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ /* SDQCR needs to be initialized to 0 when no channels are
+ * being dequeued from or else the QMan HW will indicate an
+ * error. The values that were calculated above will be
+ * applied when dequeues from a specific channel are enabled
+ */
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
+ eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);
+ p->eqcr.pi = eqcr_pi & 0xF;
+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
+ p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & 0xF;
+ p->eqcr.available = QBMAN_EQCR_SIZE - qm_cyc_diff(QBMAN_EQCR_SIZE,
+ p->eqcr.ci, p->eqcr.pi);
+
+ portal_idx_map[p->desc.idx] = p;
+ return p;
+}
+
+void qbman_swp_finish(struct qbman_swp *p)
+{
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ qbman_swp_sys_finish(&p->sys);
+ portal_idx_map[p->desc.idx] = NULL;
+ kfree(p);
+}
+
+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
+{
+ return &p->desc;
+}
+
+/**************/
+/* Interrupts */
+/**************/
+
+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
+}
+
+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
+}
+
+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
+}
+
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
+}
+
+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
+}
+
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
+}
+
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
+{
+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
+}
+
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
+{
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(!(p->mc.check != swp_mc_can_submit));
+#endif
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so.
+ */
+ QBMAN_BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ qbman_cena_invalidate_prefetch(&p->sys,
+ QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_eqdi = QB_CODE(0, 3, 1);
+static struct qb_attr_code code_eq_dca_en = QB_CODE(0, 15, 1);
+static struct qb_attr_code code_eq_dca_pk = QB_CODE(0, 14, 1);
+/* Can't set code_eq_dca_idx width. Need qman version. Read at runtime */
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_orp_is_nesn = QB_CODE(0, 31, 1);
+static struct qb_attr_code code_eq_orp_nlis = QB_CODE(0, 30, 1);
+static struct qb_attr_code code_eq_orp_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_eq_opr_id = QB_CODE(1, 0, 16);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
+static struct qb_attr_code code_eq_rsp_id = QB_CODE(5, 24, 8);
+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
+
+enum qbman_eq_cmd_e {
+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
+ uint32_t opr_id, uint32_t seqnum, int incomplete)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, !!incomplete);
+}
+
+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 0);
+}
+
+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
+ uint32_t seqnum)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 1);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
+}
+
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_rsp_id, cl, (uint32_t)token);
+}
+
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 0);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, fqid);
+}
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_eqdi, cl, !!enable);
+}
+
+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
+ uint32_t dqrr_idx, int park)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_dca_en, cl, !!enable);
+ if (enable) {
+ qb_attr_code_encode(&code_eq_dca_pk, cl, !!park);
+ qb_attr_code_encode(&code_eq_dca_idx, cl, dqrr_idx);
+ }
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+
+ pr_debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ return 0;
+}
+
+static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ return 0;
+}
+
+int qbman_swp_fill_ring(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ __attribute__((unused)) uint8_t burst_index)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ s->eqcr.available += diff;
+ if (!diff)
+ return -EBUSY;
+ }
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_EQCR((s->eqcr.pi/* +burst_index */) & 7));
+ /* word_copy(&p[1], &cl[1], 7); */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ /* word_copy(&p[8], fd, sizeof(*fd) >> 2); */
+ memcpy(&p[8], fd, sizeof(struct qbman_fd));
+
+ /* lwsync(); */
+ p[0] = cl[0] | s->eqcr.pi_vb;
+
+ s->eqcr.pi++;
+ s->eqcr.pi &= 0xF;
+ s->eqcr.available--;
+ if (!(s->eqcr.pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+
+ return 0;
+}
+
+int qbman_swp_flush_ring(struct qbman_swp *s)
+{
+ void *ptr = s->sys.addr_cena;
+
+ dcbf((uint64_t)ptr);
+ dcbf((uint64_t)ptr + 0x40);
+ dcbf((uint64_t)ptr + 0x80);
+ dcbf((uint64_t)ptr + 0xc0);
+ dcbf((uint64_t)ptr + 0x100);
+ dcbf((uint64_t)ptr + 0x140);
+ dcbf((uint64_t)ptr + 0x180);
+ dcbf((uint64_t)ptr + 0x1c0);
+
+ return 0;
+}
+
+void qbman_sync(void)
+{
+ lwsync();
+}
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ if (s->sys.eqcr_mode == qman_eqcr_vb_array)
+ return qbman_swp_enqueue_array_mode(s, d, fd);
+ else /* Use ring mode by default */
+ return qbman_swp_enqueue_ring_mode(s, d, fd);
+}
+
+/*************************/
+/* Static (push) dequeue */
+/*************************/
+
+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
+{
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ *enabled = (int)qb_attr_code_decode(&code, &s->sdq);
+}
+
+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
+{
+ uint16_t dqsrc;
+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
+
+ QBMAN_BUG_ON(channel_idx > 15);
+ qb_attr_code_encode(&code, &s->sdq, !!enable);
+ /* Read make the complete src map. If no channels are enabled
+ * the SDQCR must be 0 or else QMan will assert errors
+ */
+ dqsrc = (uint16_t)qb_attr_code_decode(&code_sdqcr_dqsrc, &s->sdq);
+ if (dqsrc != 0)
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
+ else
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
+
+enum qb_pull_dt_e {
+ qb_pull_dt_channel,
+ qb_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct qbman_result *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command)
+ */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ qb_attr_code_encode(&code_pull_rls, cl, 1);
+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ QBMAN_BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_workqueue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, wqid);
+}
+
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
+ enum qbman_pull_type_e dct)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, dct);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_channel);
+ qb_attr_code_encode(&code_pull_dqsource, cl, chid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
+ return -EBUSY;
+ }
+ s->vdq.storage = *(void **)&cl[4];
+ /* We use portal index +1 as token so that 0 still indicates
+ * that the result isn't valid yet.
+ */
+ qb_attr_code_encode(&code_pull_token, cl, s->desc.idx + 1);
+ p = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ word_copy(&p[1], &cl[1], 3);
+ /* Set the verb byte, have to substitute in the valid-bit */
+ lwsync();
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+static struct qb_attr_code code_dqrr_seqnum = QB_CODE(0, 16, 14);
+static struct qb_attr_code code_dqrr_odpid = QB_CODE(1, 0, 16);
+/* static struct qb_attr_code code_dqrr_tok = QB_CODE(1, 24, 8); */
+static struct qb_attr_code code_dqrr_fqid = QB_CODE(2, 0, 24);
+static struct qb_attr_code code_dqrr_byte_count = QB_CODE(4, 0, 32);
+static struct qb_attr_code code_dqrr_frame_count = QB_CODE(5, 0, 24);
+static struct qb_attr_code code_dqrr_ctx_lo = QB_CODE(6, 0, 32);
+
+#define QBMAN_RESULT_DQ 0x60
+#define QBMAN_RESULT_FQRN 0x21
+#define QBMAN_RESULT_FQRNI 0x22
+#define QBMAN_RESULT_FQPN 0x24
+#define QBMAN_RESULT_FQDAN 0x25
+#define QBMAN_RESULT_CDAN 0x26
+#define QBMAN_RESULT_CSCN_MEM 0x27
+#define QBMAN_RESULT_CGCU 0x28
+#define QBMAN_RESULT_BPSCN 0x29
+#define QBMAN_RESULT_CSCN_WQ 0x2a
+
+static struct qb_attr_code code_dqpi_pi = QB_CODE(0, 0, 4);
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ uint32_t verb;
+ uint32_t response_verb;
+ uint32_t flags;
+ const struct qbman_result *dq;
+ const uint32_t *p;
+
+ /* Before using valid-bit to detect if something is there, we have to
+ * handle the case of the DQRR reset bug...
+ */
+ if (unlikely(s->dqrr.reset_bug)) {
+ /* We pick up new entries by cache-inhibited producer index,
+ * which means that a non-coherent mapping would require us to
+ * invalidate and read *only* once that PI has indicated that
+ * there's an entry here. The first trip around the DQRR ring
+ * will be much less efficient than all subsequent trips around
+ * it...
+ */
+ uint32_t dqpi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI);
+ uint32_t pi = qb_attr_code_decode(&code_dqpi_pi, &dqpi);
+ /* there are new entries iff pi != next_idx */
+ if (pi == s->dqrr.next_idx)
+ return NULL;
+ /* if next_idx is/was the last ring index, and 'pi' is
+ * different, we can disable the workaround as all the ring
+ * entries have now been DMA'd to so valid-bit checking is
+ * repaired. Note: this logic needs to be based on next_idx
+ * (which increments one at a time), rather than on pi (which
+ * can burst and wrap-around between our snapshots of it).
+ */
+ QBMAN_BUG_ON((s->dqrr.dqrr_size - 1) < 0);
+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1u)) {
+ pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
+ s->dqrr.next_idx, pi);
+ s->dqrr.reset_bug = 0;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ }
+ dq = qbman_cena_read_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)
+ return NULL;
+
+ /* There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found.
+ */
+ s->dqrr.next_idx++;
+ if (s->dqrr.next_idx == s->dqrr.dqrr_size) {
+ s->dqrr.next_idx = 0;
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+ }
+ /* If this is the final response to a volatile dequeue command
+ * indicate that the vdq is no longer busy.
+ */
+ flags = qbman_result_DQ_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_RESULT_DQ) &&
+ (flags & QBMAN_DQ_STAT_VOLATILE) &&
+ (flags & QBMAN_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+int qbman_result_has_new_result(__attribute__((unused)) struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* Entry is valid - overwrite token back to 0 so
+ * a) If this memory is reused tokesn will be 0
+ * b) If someone calls "has_new_result()" again on this entry it
+ * will not appear to be new
+ */
+ qb_attr_code_encode(&code_dqrr_tok_detect, &p[1], 0);
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice...
+ */
+ make_le32_n(p, 16);
+ return 1;
+}
+
+int qbman_check_command_complete(struct qbman_swp *s,
+ const struct qbman_result *dq)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in...
+ */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective.
+ */
+ uint32_t *p = (uint32_t *)(unsigned long)qb_cl(dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token == 0)
+ return 0;
+ /* TODO: Remove qbman_swp from parameters and make it a local
+ * once we've tested the reserve portal map change
+ */
+ s = portal_idx_map[token - 1];
+ /* When token is set it indicates that VDQ command has been fetched
+ * by qbman and is working on it. It is safe for software to issue
+ * another VDQ command, so incrementing the busy variable.
+ */
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
+ return 1;
+}
+
+/********************************/
+/* Categorising qbman results */
+/********************************/
+
+static struct qb_attr_code code_result_in_mem =
+ QB_CODE(0, QBMAN_RESULT_VERB_OFFSET_IN_MEM, 7);
+
+static inline int __qbman_result_is_x(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return (response_verb == x);
+}
+
+static inline int __qbman_result_is_x_in_mem(const struct qbman_result *dq,
+ uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_result_in_mem, p);
+
+ return (response_verb == x);
+}
+
+int qbman_result_is_DQ(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
+}
+
+int qbman_result_is_FQDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
+}
+
+int qbman_result_is_CDAN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
+}
+
+int qbman_result_is_CSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CSCN_MEM) ||
+ __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
+}
+
+int qbman_result_is_BPSCN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_BPSCN);
+}
+
+int qbman_result_is_CGCU(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CGCU);
+}
+
+int qbman_result_is_FQRN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRN);
+}
+
+int qbman_result_is_FQRNI(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRNI);
+}
+
+int qbman_result_is_FQPN(const struct qbman_result *dq)
+{
+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_result_is_DQ() is TRUE */
+
+uint32_t qbman_result_DQ_flags(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+uint16_t qbman_result_DQ_seqnum(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_seqnum, p);
+}
+
+uint16_t qbman_result_DQ_odpid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (uint16_t)qb_attr_code_decode(&code_dqrr_odpid, p);
+}
+
+uint32_t qbman_result_DQ_fqid(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_fqid, p);
+}
+
+uint32_t qbman_result_DQ_byte_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_byte_count, p);
+}
+
+uint32_t qbman_result_DQ_frame_count(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_frame_count, p);
+}
+
+uint64_t qbman_result_DQ_fqd_ctx(const struct qbman_result *dq)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(dq);
+
+ return qb_attr_code_decode_64(&code_dqrr_ctx_lo, p);
+}
+
+const struct qbman_fd *qbman_result_DQ_fd(const struct qbman_result *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct qbman_fd *)&p[8];
+}
+
+/**************************************/
+/* Parsing state-change notifications */
+/**************************************/
+
+static struct qb_attr_code code_scn_state = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_scn_rid = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_scn_state_in_mem =
+ QB_CODE(0, SCN_STATE_OFFSET_IN_MEM, 8);
+static struct qb_attr_code code_scn_rid_in_mem =
+ QB_CODE(1, SCN_RID_OFFSET_IN_MEM, 24);
+static struct qb_attr_code code_scn_ctx_lo = QB_CODE(2, 0, 32);
+
+uint8_t qbman_result_SCN_state(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state, p);
+}
+
+uint32_t qbman_result_SCN_rid(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return qb_attr_code_decode(&code_scn_rid, p);
+}
+
+uint64_t qbman_result_SCN_ctx(const struct qbman_result *scn)
+{
+ const uint64_t *p = (const uint64_t *)qb_cl(scn);
+
+ return qb_attr_code_decode_64(&code_scn_ctx_lo, p);
+}
+
+uint8_t qbman_result_SCN_state_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+
+ return (uint8_t)qb_attr_code_decode(&code_scn_state_in_mem, p);
+}
+
+uint32_t qbman_result_SCN_rid_in_mem(const struct qbman_result *scn)
+{
+ const uint32_t *p = qb_cl(scn);
+ uint32_t result_rid;
+
+ result_rid = qb_attr_code_decode(&code_scn_rid_in_mem, p);
+ return make_le24(result_rid);
+}
+
+/*****************/
+/* Parsing BPSCN */
+/*****************/
+uint16_t qbman_result_bpscn_bpid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0x3FFF;
+}
+
+int qbman_result_bpscn_has_free_bufs(const struct qbman_result *scn)
+{
+ return !(int)(qbman_result_SCN_state_in_mem(scn) & 0x1);
+}
+
+int qbman_result_bpscn_is_depleted(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x2);
+}
+
+int qbman_result_bpscn_is_surplus(const struct qbman_result *scn)
+{
+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x4);
+}
+
+uint64_t qbman_result_bpscn_ctx(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)make_le32(ctx_hi) << 32 |
+ (uint64_t)make_le32(ctx_lo));
+}
+
+/*****************/
+/* Parsing CGCU */
+/*****************/
+uint16_t qbman_result_cgcu_cgid(const struct qbman_result *scn)
+{
+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0xFFFF;
+}
+
+uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn)
+{
+ uint64_t ctx;
+ uint32_t ctx_hi, ctx_lo;
+
+ ctx = qbman_result_SCN_ctx(scn);
+ ctx_hi = upper32(ctx);
+ ctx_lo = lower32(ctx);
+ return ((uint64_t)(make_le32(ctx_hi) & 0xFF) << 32) |
+ (uint64_t)make_le32(ctx_lo);
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_rcdi = QB_CODE(0, 6, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_rcdi, cl, !!enable);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+
+ pr_debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers.
+ */
+ lwsync();
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete_wo_shadow(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t rslt, num;
+
+ QBMAN_BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) !=
+ QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ QBMAN_BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
+
+/*****************/
+/* FQ management */
+/*****************/
+
+static struct qb_attr_code code_fqalt_fqid = QB_CODE(1, 0, 32);
+
+static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
+ uint8_t alt_fq_verb)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ qb_attr_code_encode(&code_fqalt_fqid, p, fqid);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | alt_fq_verb);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p) != alt_fq_verb);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
+ fqid, alt_fq_verb, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
+}
+
+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
+}
+
+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
+}
+
+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
+{
+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
+}
+
+/**********************/
+/* Channel management */
+/**********************/
+
+static struct qb_attr_code code_cdan_cid = QB_CODE(0, 16, 12);
+static struct qb_attr_code code_cdan_we = QB_CODE(1, 0, 8);
+static struct qb_attr_code code_cdan_en = QB_CODE(1, 8, 1);
+static struct qb_attr_code code_cdan_ctx_lo = QB_CODE(2, 0, 32);
+
+/* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
+ * would be irresponsible to expose it.
+ */
+#define CODE_CDAN_WE_EN 0x1
+#define CODE_CDAN_WE_CTX 0x4
+
+static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
+ uint8_t we_mask, uint8_t cdan_en,
+ uint64_t ctx)
+{
+ uint32_t *p;
+ uint32_t rslt;
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_cdan_cid, p, channelid);
+ qb_attr_code_encode(&code_cdan_we, p, we_mask);
+ qb_attr_code_encode(&code_cdan_en, p, cdan_en);
+ qb_attr_code_encode_64(&code_cdan_ctx_lo, (uint64_t *)p, ctx);
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_WQCHAN_CONFIGURE);
+
+ /* Decode the outcome */
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ QBMAN_BUG_ON(qb_attr_code_decode(&code_generic_verb, p)
+ != QBMAN_WQCHAN_CONFIGURE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ pr_err("CDAN cQID %d failed: code = 0x%02x\n",
+ channelid, rslt);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_CTX,
+ 0, ctx);
+}
+
+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 1, 0);
+}
+
+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN,
+ 0, 0);
+}
+
+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
+ uint64_t ctx)
+{
+ return qbman_swp_CDAN_set(s, channelid,
+ CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
+ 1, ctx);
+}
+
+uint8_t qbman_get_dqrr_idx(struct qbman_result *dqrr)
+{
+ return QBMAN_IDX_FROM_DQRR(dqrr);
+}
+
+struct qbman_result *qbman_get_dqrr_from_idx(struct qbman_swp *s, uint8_t idx)
+{
+ struct qbman_result *dq;
+
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(idx));
+ return dq;
+}
+
+int qbman_swp_send_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd,
+ int frames_to_send)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqcr_ci;
+ uint8_t diff;
+ int sent = 0;
+ int i;
+ int initial_pi = s->eqcr.pi;
+ uint64_t start_pointer;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ s->eqcr.ci = qbman_cena_read_reg(&s->sys,
+ QBMAN_CENA_SWP_EQCR_CI) & 0xF;
+ diff = qm_cyc_diff(QBMAN_EQCR_SIZE,
+ eqcr_ci, s->eqcr.ci);
+ if (!diff)
+ goto done;
+ s->eqcr.available += diff;
+ }
+
+ /* we are trying to send frames_to_send,
+ * if we have enough space in the ring
+ */
+ while (s->eqcr.available && frames_to_send--) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+ /* Write command (except of first byte) and FD */
+ memcpy(&p[1], &cl[1], 7 * 4);
+ memcpy(&p[8], &fd[sent], sizeof(struct qbman_fd));
+
+ initial_pi++;
+ initial_pi &= 0xF;
+ s->eqcr.available--;
+ sent++;
+ }
+
+done:
+ initial_pi = s->eqcr.pi;
+ lwsync();
+
+ /* in order for flushes to complete faster:
+ * we use a following trick: we record all lines in 32 bit word
+ */
+
+ initial_pi = s->eqcr.pi;
+ for (i = 0; i < sent; i++) {
+ p = qbman_cena_write_start_wo_shadow_fast(&s->sys,
+ QBMAN_CENA_SWP_EQCR((initial_pi) & 7));
+
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ initial_pi++;
+ initial_pi &= 0xF;
+
+ if (!(initial_pi & 7))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ initial_pi = s->eqcr.pi;
+
+ /* We need to flush all the lines but without
+ * load/store operations between them.
+ * We assign start_pointer before we start loop so that
+ * in loop we do not read it from memory
+ */
+ start_pointer = (uint64_t)s->sys.addr_cena;
+ for (i = 0; i < sent; i++) {
+ p = (uint32_t *)(start_pointer
+ + QBMAN_CENA_SWP_EQCR(initial_pi & 7));
+ dcbf((uint64_t)p);
+ initial_pi++;
+ initial_pi &= 0xF;
+ }
+
+ /* Update producer index for the next call */
+ s->eqcr.pi = initial_pi;
+
+ return sent;
+}
+
+int qbman_get_version(void)
+{
+ return qman_version;
+}
diff --git a/drivers/bus/fslmc/qbman/qbman_portal.h b/drivers/bus/fslmc/qbman/qbman_portal.h
new file mode 100644
index 0000000..7aa1d4f
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/qbman_portal.h
@@ -0,0 +1,277 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 "qbman_private.h"
+#include <fsl_qbman_portal.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* QBMan DQRR size is set at runtime in qbman_portal.c */
+
+#define QBMAN_EQCR_SIZE 8
+
+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return last - first;
+ return (2 * ringsize) + last - first;
+}
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ struct qbman_swp_desc desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here.
+ */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * to whether or not a command can be submitted, not whether or
+ * not a previously-submitted command is still executing. In
+ * other words, once proof is seen that the previously-submitted
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ /* We need to determine when vdq is no longer busy. This depends
+ * on whether the "busy" (last-submitted) dequeue command is
+ * targeting DQRR or main-memory, and detected is based on the
+ * presence of the dequeue command's "token" showing up in
+ * dequeue entries in DQRR or main-memory (respectively).
+ */
+ struct qbman_result *storage; /* NULL if DQRR */
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ uint8_t dqrr_size;
+ int reset_bug;
+ } dqrr;
+ struct {
+ uint32_t pi;
+ uint32_t pi_vb;
+ uint32_t ci;
+ int available;
+ } eqcr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete).
+ */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and DPAA2 QBMan is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Some pre-defined codes */
+extern struct qb_attr_code code_generic_verb;
+extern struct qb_attr_code code_generic_rslt;
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+#define QB_CODE_NULL \
+ QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
+
+/* Rotate a code "ms", meaning that it moves from less-significant bytes to
+ * more-significant, from less-significant words to more-significant, etc. The
+ * "ls" version does the inverse, from more-significant towards
+ * less-significant.
+ */
+static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ code->lsoffset += bits;
+ while (code->lsoffset > 31) {
+ code->word++;
+ code->lsoffset -= 32;
+ }
+}
+
+static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
+ unsigned int bits)
+{
+ /* Don't be fooled, this trick should work because the types are
+ * unsigned. So the case that interests the while loop (the rotate has
+ * gone too far and the word count needs to compensate for it), is
+ * manifested when lsoffset is negative. But that equates to a really
+ * large unsigned value, starting with lots of "F"s. As such, we can
+ * continue adding 32 back to it until it wraps back round above zero,
+ * to a value of 31 or less...
+ */
+ code->lsoffset -= bits;
+ while (code->lsoffset > 31) {
+ code->word--;
+ code->lsoffset += 32;
+ }
+}
+
+/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
+#define qb_attr_code_for_ms(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ms(code, bits))
+#define qb_attr_code_for_ls(code, bits, expr) \
+ for (; expr; qb_attr_code_rotate_ls(code, bits))
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
+}
+
+static inline uint64_t qb_attr_code_decode_64(const struct qb_attr_code *code,
+ const uint64_t *cacheline)
+{
+ return cacheline[code->word / 2];
+}
+
+/* encode a field to a cacheline */
+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
+ uint32_t *cacheline, uint32_t val)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
+/* Small-width signed values (two's-complement) will decode into medium-width
+ * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
+ * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
+ * 249. Likewise -120 would decode as 136.) This function allows the caller to
+ * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
+ * encoding, will become 0xfffffff9 if you cast the return value to uint32_t).
+ */
+static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
+ uint32_t val)
+{
+ QBMAN_BUG_ON(val >= (1u << code->width));
+ /* code->width should never exceed the width of val. If it does then a
+ * different function with larger val size must be used to translate
+ * from unsigned to signed
+ */
+ QBMAN_BUG_ON(code->width > sizeof(val) * CHAR_BIT);
+ /* If the high bit was set, it was encoding a negative */
+ if (val >= 1u << (code->width - 1))
+ return (int32_t)0 - (int32_t)(((uint32_t)1 << code->width) -
+ val);
+ /* Otherwise, it was encoding a positive */
+ return (int32_t)val;
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * a "descriptor" type that the caller can instantiate however they like.
+ * Ultimately though, it is just a cacheline of binary storage (or something
+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
+ * holding pre-formatted pieces of hardware commands. The performance-critical
+ * code can then copy these descriptors directly into hardware command
+ * registers more efficiently than trying to construct/format commands
+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/bus/fslmc/qbman/qbman_private.h b/drivers/bus/fslmc/qbman/qbman_private.h
new file mode 100644
index 0000000..f5fa13d
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/qbman_private.h
@@ -0,0 +1,170 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+/* Perform extra checking */
+#define QBMAN_CHECKING
+
+/* To maximise the amount of logic that is common between the Linux driver and
+ * other targets (such as the embedded MC firmware), we pivot here between the
+ * inclusion of two platform-specific headers.
+ *
+ * The first, qbman_sys_decl.h, includes any and all required system headers as
+ * well as providing any definitions for the purposes of compatibility. The
+ * second, qbman_sys.h, is where platform-specific routines go.
+ *
+ * The point of the split is that the platform-independent code (including this
+ * header) may depend on platform-specific declarations, yet other
+ * platform-specific routines may depend on platform-independent definitions.
+ */
+
+#include "qbman_sys_decl.h"
+
+/* When things go wrong, it is a convenient trick to insert a few FOO()
+ * statements in the code to trace progress. TODO: remove this once we are
+ * hacking the code less actively.
+ */
+#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+do { \
+ if (!(loopvar--)) \
+ QBMAN_BUG_ON(NULL == "DBG_POLL_CHECK"); \
+} while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ QBMAN_BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ pr_info("%s", buf);
+ }
+}
+
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#include "qbman_sys.h"
diff --git a/drivers/bus/fslmc/qbman/qbman_sys.h b/drivers/bus/fslmc/qbman/qbman_sys.h
new file mode 100644
index 0000000..5dbcaa5
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/qbman_sys.h
@@ -0,0 +1,385 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required.
+ */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness.
+ */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+
+static inline uint32_t make_le24(uint32_t val)
+{
+ return (((val & 0xff) << 16) | (val & 0xff00) |
+ ((val & 0xff0000) >> 16));
+}
+
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+#else
+#define make_le32(val) (val)
+#define make_le24(val) (val)
+#define make_le32_n(val, len) do {} while (0)
+#endif
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder.
+ */
+ uint8_t *cena;
+ uint8_t __iomem *addr_cena;
+ uint8_t __iomem *addr_cinh;
+ uint32_t idx;
+ enum qbman_eqcr_mode eqcr_mode;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:%d:0x%03x) 0x%08x\n",
+ s->addr_cinh, s->idx, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void *qbman_cena_write_start_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 1; loop--)
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+ lwsync();
+ __raw_writel(shadow[0], s->addr_cena + offset);
+ dcbf(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_write_complete_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+ hexdump(cmd, 64);
+#endif
+ dcbf(s->addr_cena + offset);
+}
+
+static inline uint32_t qbman_cena_read_reg(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ return __raw_readl(s->addr_cena + offset);
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = (uint32_t *)(s->cena + offset);
+ unsigned int loop;
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void *qbman_cena_read_wo_shadow(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:%d:0x%03x) %p\n",
+ s->addr_cena, s->idx, offset, shadow);
+#endif
+
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return s->addr_cena + offset;
+}
+
+static inline void qbman_cena_invalidate(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ dccivac(s->addr_cena + offset);
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+static inline void qbman_cena_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ prefetch_for_load(s->addr_cena + offset);
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here.
+ */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x2)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x2)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- TRUE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- TRUE)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- TRUE)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- TRUE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) |
+ e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d,
+ uint8_t dqrr_size)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->idx = (uint32_t)d->idx;
+ s->cena = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!s->cena) {
+ pr_err("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+ s->eqcr_mode = d->eqcr_mode;
+ QBMAN_BUG_ON(d->idx < 0);
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ QBMAN_BUG_ON(reg);
+#endif
+ if (s->eqcr_mode == qman_eqcr_vb_array)
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 1, 1, 1, 1,
+ 1, 1);
+ else
+ reg = qbman_set_swp_cfg(dqrr_size, 0, 2, 3, 2, 2, 1, 1, 1, 1,
+ 1, 1);
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ pr_err("The portal %d is not enabled!\n", s->idx);
+ kfree(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free_page((unsigned long)s->cena);
+}
+
+static inline void *
+qbman_cena_write_start_wo_shadow_fast(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:%d:0x%03x)\n",
+ s->addr_cena, s->idx, offset);
+#endif
+ QBMAN_BUG_ON(offset & 63);
+ return (s->addr_cena + offset);
+}
diff --git a/drivers/bus/fslmc/qbman/qbman_sys_decl.h b/drivers/bus/fslmc/qbman/qbman_sys_decl.h
new file mode 100644
index 0000000..e52f5ed
--- /dev/null
+++ b/drivers/bus/fslmc/qbman/qbman_sys_decl.h
@@ -0,0 +1,73 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ *
+ * 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 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 Freescale Semiconductor ``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 Freescale Semiconductor 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 <compat.h>
+#include <fsl_qbman_base.h>
+
+/* Sanity check */
+#if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && \
+ (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
+#error "Unknown endianness!"
+#endif
+
+/* The platform-independent code shouldn't need endianness, except for
+ * weird/fast-path cases like qbman_result_has_token(), which needs to
+ * perform a passive and endianness-specific test on a read-only data structure
+ * very quickly. It's an exception, and this symbol is used for that case.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define DQRR_TOK_OFFSET 0
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 24
+#define SCN_STATE_OFFSET_IN_MEM 8
+#define SCN_RID_OFFSET_IN_MEM 8
+#else
+#define DQRR_TOK_OFFSET 24
+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 0
+#define SCN_STATE_OFFSET_IN_MEM 16
+#define SCN_RID_OFFSET_IN_MEM 0
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
+#define lwsync() { asm volatile("dmb st" : : : "memory"); }
+#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); }
+#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); }
+static inline void prefetch_for_load(void *p)
+{
+ asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p));
+}
+
+static inline void prefetch_for_store(void *p)
+{
+ asm volatile("prfm pstl1keep, [%0, #64]" : : "r" (p));
+}
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 41c80d9..95c1804 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,25 @@
DPDK_17.05 {
global:
+ qbman_check_command_complete;
+ qbman_eq_desc_clear;
+ qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_qd;
+ qbman_eq_desc_set_response;
+ qbman_get_version;
+ qbman_pull_desc_clear;
+ qbman_pull_desc_set_fq;
+ qbman_pull_desc_set_numframes;
+ qbman_pull_desc_set_storage;
+ qbman_release_desc_clear;
+ qbman_release_desc_set_bpid;
+ qbman_result_DQ_fd;
+ qbman_result_DQ_flags;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
+ qbman_swp_pull;
+ qbman_swp_release;
+ qbman_swp_send_multiple;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 05/46] bus/fslmc: introduce MC object functions
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (3 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 04/46] bus/fslmc: add QBMAN driver to bus Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 06/46] bus/fslmc: add mc dpio object support Hemant Agrawal
` (43 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch intoduces the DPAA2 MC(Management complex Driver).
This is a minimal set of low level functions to send and
receive commands to the fsl-mc. It includes support for basic
management commands and commands to manipulate MC objects.
This is common to be used by various DPAA2 PMDs. e.g.net, crypto
and other drivers.
This is a low level library also used in kernel.
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 4 +
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 238 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 105 ++++++++++++
drivers/bus/fslmc/mc/mc_sys.c | 114 +++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
5 files changed, 462 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 7368ce0..0b09fe6 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -50,6 +50,7 @@ endif
CFLAGS += "-Wno-strict-aliasing"
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
@@ -62,6 +63,9 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
qbman/qbman_portal.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/mc_sys.c
+
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
# library dependencies
diff --git a/drivers/bus/fslmc/mc/fsl_mc_cmd.h b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
new file mode 100644
index 0000000..bc41646
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_cmd.h
@@ -0,0 +1,238 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#define MC_CMD_NUM_OF_PARAMS 7
+
+#define MAKE_UMASK64(_width) \
+ ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : \
+ (uint64_t)-1))
+
+static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val)
+{
+ return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+
+static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width)
+{
+ return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+struct mc_command {
+ uint64_t header;
+ uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+/**
+ * enum mc_cmd_status - indicates MC status at command response
+ * @MC_CMD_STATUS_OK: Completed successfully
+ * @MC_CMD_STATUS_READY: Ready to be processed
+ * @MC_CMD_STATUS_AUTH_ERR: Authentication error
+ * @MC_CMD_STATUS_NO_PRIVILEGE: No privilege
+ * @MC_CMD_STATUS_DMA_ERR: DMA or I/O error
+ * @MC_CMD_STATUS_CONFIG_ERR: Configuration error
+ * @MC_CMD_STATUS_TIMEOUT: Operation timed out
+ * @MC_CMD_STATUS_NO_RESOURCE: No resources
+ * @MC_CMD_STATUS_NO_MEMORY: No memory available
+ * @MC_CMD_STATUS_BUSY: Device is busy
+ * @MC_CMD_STATUS_UNSUPPORTED_OP: Unsupported operation
+ * @MC_CMD_STATUS_INVALID_STATE: Invalid state
+ */
+enum mc_cmd_status {
+ MC_CMD_STATUS_OK = 0x0,
+ MC_CMD_STATUS_READY = 0x1,
+ MC_CMD_STATUS_AUTH_ERR = 0x3,
+ MC_CMD_STATUS_NO_PRIVILEGE = 0x4,
+ MC_CMD_STATUS_DMA_ERR = 0x5,
+ MC_CMD_STATUS_CONFIG_ERR = 0x6,
+ MC_CMD_STATUS_TIMEOUT = 0x7,
+ MC_CMD_STATUS_NO_RESOURCE = 0x8,
+ MC_CMD_STATUS_NO_MEMORY = 0x9,
+ MC_CMD_STATUS_BUSY = 0xA,
+ MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,
+ MC_CMD_STATUS_INVALID_STATE = 0xC
+};
+
+/* MC command flags */
+
+/**
+ * High priority flag
+ */
+#define MC_CMD_FLAG_PRI 0x00008000
+/**
+ * Command completion flag
+ */
+#define MC_CMD_FLAG_INTR_DIS 0x01000000
+
+/**
+ * Command ID field offset
+ */
+#define MC_CMD_HDR_CMDID_O 48
+/**
+ * Command ID field size
+ */
+#define MC_CMD_HDR_CMDID_S 16
+/**
+ * Token field offset
+ */
+#define MC_CMD_HDR_TOKEN_O 32
+/**
+ * Token field size
+ */
+#define MC_CMD_HDR_TOKEN_S 16
+/**
+ * Status field offset
+ */
+#define MC_CMD_HDR_STATUS_O 16
+/**
+ * Status field size
+ */
+#define MC_CMD_HDR_STATUS_S 8
+/**
+ * Flags field offset
+ */
+#define MC_CMD_HDR_FLAGS_O 0
+/**
+ * Flags field size
+ */
+#define MC_CMD_HDR_FLAGS_S 32
+/**
+ * Command flags mask
+ */
+#define MC_CMD_HDR_FLAGS_MASK 0xFF00FF00
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+ ((enum mc_cmd_status)mc_dec((_hdr), \
+ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
+
+#define MC_PREP_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= cpu_to_le64(mc_enc((_offset), (_width), _arg)))
+
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(cpu_to_le64(_ext[_param]), (_offset), (_width)))
+
+#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg))
+
+#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
+ (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width)))
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, object_id)
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ uint64_t hdr;
+
+ hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+ hdr |= mc_enc(MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S,
+ (cmd_flags & MC_CMD_HDR_FLAGS_MASK));
+ hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
+ hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+ MC_CMD_STATUS_READY);
+
+ return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+ struct mc_command *cmd)
+{
+ int i;
+ uint32_t word;
+
+ /* copy command parameters into the portal */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ iowrite64(cmd->params[i], &portal->params[i]);
+
+ /* submit the command by writing the header */
+ word = (uint32_t)mc_dec(cmd->header, 32, 32);
+ iowrite32(word, (((uint32_t *)&portal->header) + 1));
+
+ word = (uint32_t)mc_dec(cmd->header, 0, 32);
+ iowrite32(word, (uint32_t *)&portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(
+ struct mc_command __iomem *portal,
+ struct mc_command *resp)
+{
+ int i;
+ enum mc_cmd_status status;
+
+ /* Copy command response header from MC portal: */
+ resp->header = ioread64(&portal->header);
+ status = MC_CMD_HDR_READ_STATUS(resp->header);
+ if (status != MC_CMD_STATUS_OK)
+ return status;
+
+ /* Copy command response data from MC portal: */
+ for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+ resp->params[i] = ioread64(&portal->params[i]);
+
+ return status;
+}
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/drivers/bus/fslmc/mc/fsl_mc_sys.h b/drivers/bus/fslmc/mc/fsl_mc_sys.h
new file mode 100644
index 0000000..ebada60
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_mc_sys.h
@@ -0,0 +1,105 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#ifdef __linux_driver__
+
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/slab.h>
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+
+#else /* __linux_driver__ */
+
+#include <stdio.h>
+#include <libio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <linux/byteorder/little_endian.h>
+
+#define cpu_to_le64(x) __cpu_to_le64(x)
+#ifndef dmb
+#define dmb() {__asm__ __volatile__("" : : : "memory"); }
+#endif
+#define __iormb() dmb()
+#define __iowmb() dmb()
+#define __arch_getq(a) (*(volatile unsigned long *)(a))
+#define __arch_putq(v, a) (*(volatile unsigned long *)(a) = (v))
+#define __arch_putq32(v, a) (*(volatile unsigned int *)(a) = (v))
+#define readq(c) \
+ ({ uint64_t __v = __arch_getq(c); __iormb(); __v; })
+#define writeq(v, c) \
+ ({ uint64_t __v = v; __iowmb(); __arch_putq(__v, c); __v; })
+#define writeq32(v, c) \
+ ({ uint32_t __v = v; __iowmb(); __arch_putq32(__v, c); __v; })
+#define ioread64(_p) readq(_p)
+#define iowrite64(_v, _p) writeq(_v, _p)
+#define iowrite32(_v, _p) writeq32(_v, _p)
+#define __iomem
+
+struct fsl_mc_io {
+ void *regs;
+};
+
+#ifndef ENOTSUP
+#define ENOTSUP 95
+#endif
+
+/*GPP is supposed to use MC commands with low priority*/
+#define CMD_PRI_LOW 0 /*!< Low Priority command indication */
+
+struct mc_command;
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* __linux_driver__ */
+
+#endif /* _FSL_MC_SYS_H */
diff --git a/drivers/bus/fslmc/mc/mc_sys.c b/drivers/bus/fslmc/mc/mc_sys.c
new file mode 100644
index 0000000..4573165
--- /dev/null
+++ b/drivers/bus/fslmc/mc/mc_sys.c
@@ -0,0 +1,114 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+
+#include <rte_spinlock.h>
+
+/** User space framework uses MC Portal in shared mode. Following change
+ * introduces lock in MC FLIB
+ */
+
+/**
+ * A static spinlock initializer.
+ */
+static rte_spinlock_t mc_portal_lock = RTE_SPINLOCK_INITIALIZER;
+
+static int mc_status_to_error(enum mc_cmd_status status)
+{
+ switch (status) {
+ case MC_CMD_STATUS_OK:
+ return 0;
+ case MC_CMD_STATUS_AUTH_ERR:
+ return -EACCES; /* Token error */
+ case MC_CMD_STATUS_NO_PRIVILEGE:
+ return -EPERM; /* Permission denied */
+ case MC_CMD_STATUS_DMA_ERR:
+ return -EIO; /* Input/Output error */
+ case MC_CMD_STATUS_CONFIG_ERR:
+ return -EINVAL; /* Device not configured */
+ case MC_CMD_STATUS_TIMEOUT:
+ return -ETIMEDOUT; /* Operation timed out */
+ case MC_CMD_STATUS_NO_RESOURCE:
+ return -ENAVAIL; /* Resource temporarily unavailable */
+ case MC_CMD_STATUS_NO_MEMORY:
+ return -ENOMEM; /* Cannot allocate memory */
+ case MC_CMD_STATUS_BUSY:
+ return -EBUSY; /* Device busy */
+ case MC_CMD_STATUS_UNSUPPORTED_OP:
+ return -ENOTSUP; /* Operation not supported by device */
+ case MC_CMD_STATUS_INVALID_STATE:
+ return -ENODEV; /* Invalid device state */
+ default:
+ break;
+ }
+
+ /* Not expected to reach here */
+ return -EINVAL;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+ enum mc_cmd_status status;
+
+ if (!mc_io || !mc_io->regs)
+ return -EACCES;
+
+ /* --- Call lock function here in case portal is shared --- */
+ rte_spinlock_lock(&mc_portal_lock);
+
+ mc_write_command(mc_io->regs, cmd);
+
+ /* Spin until status changes */
+ do {
+ status = MC_CMD_HDR_READ_STATUS(ioread64(mc_io->regs));
+
+ /* --- Call wait function here to prevent blocking ---
+ * Change the loop condition accordingly to exit on timeout.
+ */
+ } while (status == MC_CMD_STATUS_READY);
+
+ /* Read the response back into the command buffer */
+ mc_read_response(mc_io->regs, cmd);
+
+ /* --- Call unlock function here in case portal is shared --- */
+ rte_spinlock_unlock(&mc_portal_lock);
+
+ return mc_status_to_error(status);
+}
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 95c1804..9b0fec5 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,7 @@
DPDK_17.05 {
global:
+ mc_send_command;
qbman_check_command_complete;
qbman_eq_desc_clear;
qbman_eq_desc_set_no_orp;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 06/46] bus/fslmc: add mc dpio object support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (4 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 05/46] bus/fslmc: introduce MC object functions Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 07/46] bus/fslmc: add mc dpbp " Hemant Agrawal
` (42 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the DPIO object support in MC driver.
DPIO - Data Path Input Output represent the processing
context to access the QBMAN HW for packet I/O.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpio.c | 279 +++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio.h | 282 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 121 ++++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 7 +
5 files changed, 690 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 0b09fe6..ce9ed90 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -64,6 +64,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
qbman/qbman_portal.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/dpio.c \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/mc/dpio.c b/drivers/bus/fslmc/mc/dpio.c
new file mode 100644
index 0000000..7f7359d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpio.c
@@ -0,0 +1,279 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpio.h>
+#include <fsl_dpio_cmd.h>
+
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPIO_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
+ cmd_flags,
+ token);
+ DPIO_CMD_SET_STASHING_DEST(cmd, sdest);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_STASHING_DEST,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_STASHING_DEST(cmd, *sdest);
+
+ return 0;
+}
+
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPIO_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpio.h b/drivers/bus/fslmc/mc/fsl_dpio.h
new file mode 100644
index 0000000..6d86f07
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio.h
@@ -0,0 +1,282 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPIO_H
+#define __FSL_DPIO_H
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and any MC portals
+ * assigned to the parent container; this token must be used in
+ * all subsequent commands for this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpio_id,
+ uint16_t *token);
+
+/**
+ * dpio_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * struct dpio_cfg - Structure representing DPIO configuration
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_cfg {
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_create() - Create the DPIO object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPIO object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpio_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpio_destroy() - Destroy the DPIO object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_is_enabled() - Check if the DPIO is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpio_set_stashing_destination() - Set the stashing destination.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t sdest);
+
+/**
+ * dpio_get_stashing_destination() - Get the stashing destination..
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @sdest: Returns the stashing destination value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t *sdest);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ * @qbman_version: QBMAN version
+ */
+struct dpio_attr {
+ int id;
+ uint64_t qbman_portal_ce_offset;
+ uint64_t qbman_portal_ci_offset;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+ uint32_t qbman_version;
+ uint32_t clk;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+/**
+ * dpio_get_api_version() - Get Data Path I/O API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path i/o API
+ * @minor_ver: Minor version of data path i/o API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPIO_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpio_cmd.h b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
new file mode 100644
index 0000000..c4b613e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpio_cmd.h
@@ -0,0 +1,121 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPIO_CMD_H
+#define _FSL_DPIO_CMD_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 4
+#define DPIO_VER_MINOR 2
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPIO_CMDID_OPEN ((0x803 << 4) | (0x1))
+#define DPIO_CMDID_CREATE ((0x903 << 4) | (0x1))
+#define DPIO_CMDID_DESTROY ((0x983 << 4) | (0x1))
+#define DPIO_CMDID_GET_API_VERSION ((0xa03 << 4) | (0x1))
+
+#define DPIO_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPIO_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPIO_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPIO_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPIO_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPIO_CMDID_SET_STASHING_DEST ((0x120 << 4) | (0x1))
+#define DPIO_CMDID_GET_STASHING_DEST ((0x121 << 4) | (0x1))
+#define DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL ((0x122 << 4) | (0x1))
+#define DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL ((0x123 << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 2, enum dpio_channel_mode, \
+ cfg->channel_mode);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->num_priorities);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
+ MC_RSP_OP(cmd, 3, 0, 32, uint32_t, attr->qbman_version);\
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, attr->clk);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_SET_STASHING_DEST(cmd, sdest) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_STASHING_DEST(cmd, sdest) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, sdest)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, channel_index) \
+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, channel_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 9b0fec5..bcd29a8 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,13 @@
DPDK_17.05 {
global:
+ dpio_close;
+ dpio_disable;
+ dpio_enable;
+ dpio_get_attributes;
+ dpio_open;
+ dpio_reset;
+ dpio_set_stashing_destination;
mc_send_command;
qbman_check_command_complete;
qbman_eq_desc_clear;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 07/46] bus/fslmc: add mc dpbp object support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (5 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 06/46] bus/fslmc: add mc dpio object support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 08/46] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
` (41 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
DPBP object represent a hw based buffer pool instance
in the DPAA2 hardware.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/mc/dpbp.c | 237 ++++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 227 ++++++++++++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 83 ++++++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 5 +
5 files changed, 553 insertions(+)
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index ce9ed90..d30cea9 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -64,6 +64,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
qbman/qbman_portal.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
+ mc/dpbp.c \
mc/dpio.c \
mc/mc_sys.c
diff --git a/drivers/bus/fslmc/mc/dpbp.c b/drivers/bus/fslmc/mc/dpbp.c
new file mode 100644
index 0000000..0d93e0c
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpbp.c
@@ -0,0 +1,237 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpbp.h>
+#include <fsl_dpbp_cmd.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ (void)(cfg); /* unused */
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPBP_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp.h b/drivers/bus/fslmc/mc/fsl_dpbp.h
new file mode 100644
index 0000000..65262bd
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp.h
@@ -0,0 +1,227 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpbp_id: DPBP unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpbp_create function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpbp_id,
+ uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_cfg - Structure representing DPBP configuration
+ * @options: place holder
+ */
+struct dpbp_cfg {
+ uint32_t options;
+};
+
+/**
+ * dpbp_create() - Create the DPBP object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPBP object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpbp_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpbp_destroy() - Destroy the DPBP object and release all its resources.
+ * @dprc_token: Parent container token; '0' for default container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpbp_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpbp_is_enabled() - Check if the DPBP is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ uint16_t bpid;
+};
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/**
+ * dpbp_get_api_version() - Get buffer pool API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path buffer pool API
+ * @minor_ver: Minor version of data path buffer pool API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+#endif /* __FSL_DPBP_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
new file mode 100644
index 0000000..a6bfabe
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
@@ -0,0 +1,83 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPBP_CMD_H
+#define _FSL_DPBP_CMD_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 3
+#define DPBP_VER_MINOR 2
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPBP_CMDID_OPEN ((0x804 << 4) | (0x1))
+#define DPBP_CMDID_CREATE ((0x904 << 4) | (0x1))
+#define DPBP_CMDID_DESTROY ((0x984 << 4) | (0x1))
+#define DPBP_CMDID_GET_API_VERSION ((0xa04 << 4) | (0x1))
+
+#define DPBP_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPBP_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPBP_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPBP_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPBP_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+#endif /* _FSL_DPBP_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index bcd29a8..b6979e8 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,11 @@
DPDK_17.05 {
global:
+ dpbp_disable;
+ dpbp_enable;
+ dpbp_get_attributes;
+ dpbp_open;
+ dpbp_reset;
dpio_close;
dpio_disable;
dpio_enable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 08/46] eal/vfio: adding vfio utility functions in map file
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (6 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 07/46] bus/fslmc: add mc dpbp " Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 09/46] bus/fslmc: add vfio support Hemant Agrawal
` (40 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
adding extra vfio utility functions to map file.
They will be used by other vfio supported buses like fslmc bus
for NXP DPAA2 devices
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +++
2 files changed, 6 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 67f2ffb..a5da528 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -180,5 +180,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 9c134b4..bbb6981 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -184,5 +184,8 @@ DPDK_17.02 {
rte_bus_register;
rte_bus_scan;
rte_bus_unregister;
+ vfio_get_container_fd;
+ vfio_get_group_fd;
+ vfio_get_group_no;
} DPDK_16.11;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 09/46] bus/fslmc: add vfio support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (7 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 08/46] eal/vfio: adding vfio utility functions in map file Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 10/46] bus/fslmc: scan for net and sec device Hemant Agrawal
` (39 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/fslmc_bus.c | 10 +
drivers/bus/fslmc/fslmc_vfio.c | 450 ++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 74 +++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
5 files changed, 536 insertions(+)
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index d30cea9..90edaad 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -68,6 +68,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 8a4f519..ee794e7 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -42,6 +42,7 @@
#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)
@@ -51,6 +52,15 @@
static int
rte_fslmc_scan(void)
{
+ if (fslmc_vfio_setup_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup VFIO");
+ return -1;
+ }
+ if (fslmc_vfio_process_group()) {
+ FSLMC_BUS_LOG(ERR, "fslmc: Unable to setup devices");
+ return -1;
+ }
+ 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
new file mode 100644
index 0000000..73db595
--- /dev/null
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -0,0 +1,450 @@
+/*-
+ * 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_FSL_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 *(*rte_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, ®_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(void)
+{
+ 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 */
+ rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
+ if (!rte_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);
+
+ rte_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)
+{
+ struct fslmc_vfio_group *group = NULL;
+ int groupid;
+ int ret, 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;
+ }
+ /* get group number */
+ ret = vfio_get_group_no(SYSFS_FSL_MC_DEVICES, container, &groupid);
+ if (ret == 0) {
+ RTE_LOG(WARNING, EAL, "%s not managed by VFIO, skipping\n",
+ container);
+ return 1;
+ }
+
+ /* if negative, something failed */
+ if (ret < 0)
+ return -1;
+
+ 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;
+ }
+ }
+
+ /* get the actual group fd */
+ group->fd = vfio_get_group_fd(groupid);
+ if (group->fd < 0)
+ return -1;
+
+ /*
+ * at this point, we know that this group is viable (meaning,
+ * all devices are either bound to VFIO or not bound to anything)
+ */
+
+ 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..5e58211
--- /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(void);
+
+#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index b6979e8..463c658 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -35,6 +35,7 @@ DPDK_17.05 {
qbman_swp_send_multiple;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_mcp_ptr_list;
local: *;
};
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 10/46] bus/fslmc: scan for net and sec device
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (8 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 09/46] bus/fslmc: add vfio support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 11/46] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (38 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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_vfio.c | 63 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 73db595..0d4c0a2 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -210,6 +210,48 @@ 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 != DPAA2_MC_DPNI_DEVID ||
+ dev->dev_type != DPAA2_MC_DPSECI_DEVID)
+ return -1;
+
+ if (dev->object_id == dev2->object_id)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+fslmc_bus_add_device(struct rte_dpaa2_device *dev)
+{
+ struct rte_fslmc_device_list *dev_l;
+
+ dev_l = &rte_fslmc_bus.device_list;
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(dev_l)) {
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ } else {
+ struct rte_dpaa2_device *dev2;
+ int ret;
+
+ TAILQ_FOREACH(dev2, dev_l, next) {
+ ret = dpaa2_compare_dpaa2_dev(dev, dev2);
+ if (ret <= 0)
+ continue;
+
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ return;
+ }
+
+ TAILQ_INSERT_TAIL(dev_l, dev, next);
+ }
+}
+
/* Following function shall fetch total available list of MC devices
* from VFIO container & populate private list of devices and other
* data structures
@@ -218,7 +260,7 @@ int fslmc_vfio_process_group(void)
{
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;
@@ -348,6 +390,25 @@ int fslmc_vfio_process_group(void)
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);
+
+ fslmc_bus_add_device(dev);
+ }
}
closedir(d);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 11/46] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (9 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 10/46] bus/fslmc: scan for net and sec device Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 12/46] doc: add DPAA2 NIC details Hemant Agrawal
` (37 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 3 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 61 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 142 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 2 +
9 files changed, 267 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/MAINTAINERS b/MAINTAINERS
index 0eda467..faca3d7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -358,7 +358,10 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
+F: drivers/net/dpaa2/
+
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
M: Rasesh Mody <rasesh.mody@cavium.com>
diff --git a/config/common_base b/config/common_base
index e7ab12f..1b58313 100644
--- a/config/common_base
+++ b/config/common_base
@@ -292,6 +292,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=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 365ae5a..e63ff56 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -46,3 +46,8 @@ CONFIG_RTE_MAX_NUMA_NODES=1
# 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/net/Makefile b/drivers/net/Makefile
index 40fc333..c2f64ce 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
DIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
@@ -57,7 +58,6 @@ 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
-
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..4f5dbf7
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,61 @@
+# 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/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+
+LDLIBS += -lrte_bus_fslmc
+
+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..bdef362
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,142 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = (struct eth_driver *)dpaa2_drv;
+
+ sprintf(ethdev_name, "dpni-%d", dpaa2_dev->object_id);
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ sizeof(struct dpaa2_dev_priv),
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL) {
+ RTE_LOG(CRIT, PMD, "Cannot allocate memzone for"
+ " private port data\n");
+ rte_eth_dev_release_port(eth_dev);
+ 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;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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..8591cc0
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.05 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d46a33e..22c22d4 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -108,6 +108,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 12/46] doc: add DPAA2 NIC details
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (10 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 11/46] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 13/46] bus/fslmc: add debug log support Hemant Agrawal
` (36 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
5 files changed, 636 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index faca3d7..3fdcf77 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -361,6 +361,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..7d7a6c5
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,614 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+ For example, the *aarch64* Linaro Toolchain, which can be obtained from
+ `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+
+2. **Linux Kernel**
+
+ It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+ Any *aarch64* supporting filesystem can be used. For example,
+ Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+ from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+As an alternative method, DPAA2 PMD can also be executed using images provided
+as part of SDK from NXP. The SDK includes all the above prerequisites necessary
+to bring up a DPAA2 board.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 87f9334..be21e8a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 357965a..a27f6b7 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -15,7 +15,6 @@ DPDK Release 17.02
firefox build/doc/html/guides/rel_notes/release_17_02.html
-
New Features
------------
@@ -250,6 +249,17 @@ New Features
See the :ref:`Elastic Flow Distributor Library <Efd_Library>` documentation in
the Programmers Guide document, for more information.
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
Resolved Issues
---------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 13/46] bus/fslmc: add debug log support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (11 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 12/46] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 14/46] net/dpaa2: " Hemant Agrawal
` (35 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_logs.h | 76 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
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_ */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 14/46] net/dpaa2: add debug log support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (12 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 13/46] bus/fslmc: add debug log support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 15/46] config: enable support for DPAA2 debug logging Hemant Agrawal
` (34 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 4f5dbf7..3e3c8d1 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 bdef362..ead6a2c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -95,8 +100,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 15/46] config: enable support for DPAA2 debug logging
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (13 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 14/46] net/dpaa2: " Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 16/46] net/dpaa2: add mc dpni object support Hemant Agrawal
` (33 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 1b58313..e8299d3 100644
--- a/config/common_base
+++ b/config/common_base
@@ -295,6 +295,11 @@ 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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index e63ff56..eb12511 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -51,3 +51,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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 16/46] net/dpaa2: add mc dpni object support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (14 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 15/46] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 17/46] bus/fslmc: dpio portal driver Hemant Agrawal
` (32 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 4 +
drivers/net/dpaa2/mc/dpni.c | 739 +++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 ++++++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 ++++++++++++++
6 files changed, 2965 insertions(+)
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 3e3c8d1..db94b45 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -43,10 +43,13 @@ else
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
endif
+CFLAGS += "-Wno-strict-aliasing"
CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -56,6 +59,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/net/dpaa2/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/dpaa2/mc/fsl_dpkg.h b/drivers/net/dpaa2/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 17/46] bus/fslmc: dpio portal driver
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (15 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 16/46] net/dpaa2: add mc dpni object support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 18/46] bus/fslmc: introduce support for hw mempool object Hemant Agrawal
` (31 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
The portal 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/Makefile | 2 +
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/fslmc_vfio.c | 17 +-
drivers/bus/fslmc/fslmc_vfio.h | 5 +
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 364 ++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 60 +++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 68 ++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
8 files changed, 518 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
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/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 90edaad..10740b5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -68,6 +68,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/dpio.c \
mc/mc_sys.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 0d4c0a2..2d7bcd9 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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
#define VFIO_MAX_CONTAINERS 1
#define FSLMC_VFIO_LOG(level, fmt, args...) \
@@ -261,12 +264,13 @@ int fslmc_vfio_process_group(void)
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;
@@ -409,9 +413,20 @@ int fslmc_vfio_process_group(void)
fslmc_bus_add_device(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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5e58211..39994dd 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -71,4 +71,9 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(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_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
new file mode 100644
index 0000000..dd6de4c
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+
+ reg_info.index = 0;
+ if (ioctl(dpio_dev->vfio_fd, VFIO_DEVICE_GET_REGION_INFO, ®_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, ®_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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
new file mode 100644
index 0000000..682f3fa
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -0,0 +1,60 @@
+/*-
+ * 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_DPIO_H_
+#define _DPAA2_HW_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);
+
+
+#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
new file mode 100644
index 0000000..6b44314
--- /dev/null
+++ b/drivers/bus/fslmc/portal/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 *(*rte_mcp_ptr_list);
+#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 463c658..2110b71 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,6 +1,7 @@
DPDK_17.05 {
global:
+ dpaa2_affine_qbman_swp;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
@@ -14,6 +15,7 @@ DPDK_17.05 {
dpio_reset;
dpio_set_stashing_destination;
mc_send_command;
+ per_lcore__dpaa2_io;
qbman_check_command_complete;
qbman_eq_desc_clear;
qbman_eq_desc_set_no_orp;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 18/46] bus/fslmc: introduce support for hw mempool object
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (16 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 17/46] bus/fslmc: dpio portal driver Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
` (30 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Each mempool instance is represented by a DPBP object
from the FSL-MC bus.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/Makefile | 1 +
drivers/bus/fslmc/fslmc_vfio.c | 9 +-
drivers/bus/fslmc/fslmc_vfio.h | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 ++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 +
6 files changed, 170 insertions(+), 1 deletion(-)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 10740b5..04751a5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
mc/mc_sys.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
+SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_vfio.c
SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc_bus.c
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 2d7bcd9..fc017fc 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -270,7 +270,7 @@ int fslmc_vfio_process_group(void)
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 +420,11 @@ int fslmc_vfio_process_group(void)
if (!ret)
dpio_count++;
}
+ if (!strcmp(object_type, "dpbp")) {
+ ret = dpaa2_create_dpbp_device(object_id);
+ if (!ret)
+ dpbp_count++;
+ }
}
closedir(d);
@@ -427,6 +432,8 @@ int fslmc_vfio_process_group(void)
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/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 39994dd..80c6869 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -76,4 +76,6 @@ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
struct vfio_device_info *obj_info,
int object_id);
+int dpaa2_create_dpbp_device(int dpbp_id);
+
#endif /* _FSLMC_VFIO_H_ */
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
new file mode 100644
index 0000000..894f632
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
@@ -0,0 +1,137 @@
+/*-
+ * 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_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 "portal/dpaa2_hw_pvt.h"
+#include "portal/dpaa2_hw_dpio.h"
+
+TAILQ_HEAD(dpbp_device_list, dpaa2_dpbp_dev);
+static struct dpbp_device_list *dpbp_dev_list; /*!< DPBP device list */
+
+int
+dpaa2_create_dpbp_device(
+ int dpbp_id)
+{
+ struct dpaa2_dpbp_dev *dpbp_node;
+ int ret;
+
+ if (!dpbp_dev_list) {
+ dpbp_dev_list = malloc(sizeof(struct dpbp_device_list));
+ if (!dpbp_dev_list) {
+ PMD_INIT_LOG(ERR, "Memory alloc failed in DPBP list\n");
+ return -1;
+ }
+ /* Initialize the DPBP List */
+ TAILQ_INIT(dpbp_dev_list);
+ }
+
+ /* Allocate DPAA2 dpbp handle */
+ dpbp_node = (struct dpaa2_dpbp_dev *)
+ malloc(sizeof(struct dpaa2_dpbp_dev));
+ if (!dpbp_node) {
+ PMD_INIT_LOG(ERR, "Memory allocation failed for DPBP Device");
+ return -1;
+ }
+
+ /* Open the dpbp object */
+ dpbp_node->dpbp.regs = rte_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;
+ rte_atomic16_init(&dpbp_node->in_use);
+
+ TAILQ_INSERT_HEAD(dpbp_dev_list, dpbp_node, next);
+
+ PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
+
+ return 0;
+}
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Get DPBP dev handle from list using index */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
+ break;
+ }
+
+ return dpbp_dev;
+}
+
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp)
+{
+ struct dpaa2_dpbp_dev *dpbp_dev = NULL;
+
+ /* Match DPBP handle and mark it free */
+ TAILQ_FOREACH(dpbp_dev, dpbp_dev_list, next) {
+ if (dpbp_dev == dpbp) {
+ rte_atomic16_dec(&dpbp_dev->in_use);
+ return;
+ }
+ }
+}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 6b44314..ad2847f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -63,6 +70,19 @@ struct dpaa2_dpio_dev {
int32_t hw_id; /**< An unique ID of this DPIO device instance */
};
+struct dpaa2_dpbp_dev {
+ TAILQ_ENTRY(dpaa2_dpbp_dev) next;
+ /**< Pointer to Next device instance */
+ struct fsl_mc_io dpbp; /** handle to DPBP portal object */
+ uint16_t token;
+ rte_atomic16_t in_use;
+ uint32_t dpbp_id; /*HW ID for DPBP object */
+};
+
/*! Global MCP list */
extern void *(*rte_mcp_ptr_list);
+
+struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
+void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
+
#endif
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 2110b71..66840b1 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,8 @@ DPDK_17.05 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_alloc_dpbp_dev;
+ dpaa2_free_dpbp_dev;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (17 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 18/46] bus/fslmc: introduce support for hw mempool object Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-07 16:24 ` Ferruh Yigit
2017-03-08 9:05 ` Olivier MATZ
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 20/46] bus/fslmc: affine dpio to crypto threads Hemant Agrawal
` (29 subsequent siblings)
48 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Adding NXP DPAA2 architecture specific mempool support.
This patch also registers a dpaa2 type MEMPOOL OPS
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 1 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +
drivers/Makefile | 1 +
drivers/pool/Makefile | 40 +++
drivers/pool/dpaa2/Makefile | 72 ++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339 ++++++++++++++++++++++++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++++
drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
mk/rte.app.mk | 1 +
10 files changed, 570 insertions(+)
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_pool_dpaa2_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 3fdcf77..ca86dd7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -361,6 +361,7 @@ M: Hemant Agrawal <hemant.agrawal@nxp.com>
M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/net/dpaa2/
+F: drivers/pool/dpaa2/
F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
diff --git a/config/common_base b/config/common_base
index e8299d3..c07a95e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -287,6 +287,11 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
#
+# Compile Support Libraries for NXP DPAA2
+#
+CONFIG_RTE_LIBRTE_DPAA2_POOL=n
+
+#
# Compile NXP DPAA2 FSL-MC Bus
#
CONFIG_RTE_LIBRTE_FSLMC_BUS=n
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index eb12511..3cdb31b 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -42,6 +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_POOL=n
+CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+
#
# Compile NXP DPAA2 FSL-MC Bus
#
diff --git a/drivers/Makefile b/drivers/Makefile
index e937449..b122c14 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -32,6 +32,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += bus
+DIRS-y += pool
DIRS-y += net
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
diff --git a/drivers/pool/Makefile b/drivers/pool/Makefile
new file mode 100644
index 0000000..3efc336
--- /dev/null
+++ b/drivers/pool/Makefile
@@ -0,0 +1,40 @@
+# 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
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += 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..c1b15fd
--- /dev/null
+++ b/drivers/pool/dpaa2/Makefile
@@ -0,0 +1,72 @@
+# 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_pool_dpaa2.a
+
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_POOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
+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/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pool_dpaa2_version.map
+
+# Lbrary version
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += dpaa2_hw_mempool.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_POOL) += drivers/bus/fslmc
+
+LDLIBS += -lrte_bus_fslmc
+
+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..0c8de51
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -0,0 +1,339 @@
+/*-
+ * 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 <mc/fsl_dpbp.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+#include "dpaa2_hw_mempool.h"
+
+struct dpaa2_bp_info rte_dpaa2_bpid_info[MAX_BPID];
+static struct dpaa2_bp_list *h_bp_list;
+
+static int
+hw_mbuf_create_pool(struct rte_mempool *mp)
+{
+ struct dpaa2_bp_list *bp_list;
+ struct dpaa2_dpbp_dev *avail_dpbp;
+ struct dpbp_attr dpbp_attr;
+ uint32_t bpid;
+ int ret;
+
+ avail_dpbp = dpaa2_alloc_dpbp_dev();
+
+ if (!avail_dpbp) {
+ PMD_DRV_LOG(ERR, "DPAA2 resources not available");
+ return -1;
+ }
+
+ if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+ ret = dpaa2_affine_qbman_swp();
+ if (ret) {
+ RTE_LOG(ERR, PMD, "Failure in affining portal\n");
+ return 0;
+ }
+ }
+
+ 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;
+
+
+ rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
+ + rte_pktmbuf_priv_size(mp);
+ rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
+ rte_dpaa2_bpid_info[bpid].bpid = bpid;
+
+ mp->pool_data = (void *)&rte_dpaa2_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)
+{
+ struct dpaa2_bp_info *bpinfo;
+ struct dpaa2_bp_list *bp;
+ struct dpaa2_dpbp_dev *dpbp_node;
+
+ if (!mp->pool_data) {
+ PMD_DRV_LOG(ERR, "Not a valid dpaa22 pool");
+ return;
+ }
+
+ bpinfo = (struct dpaa2_bp_info *)mp->pool_data;
+ bp = bpinfo->bp_list;
+ dpbp_node = bp->buf_pool.dpbp_node;
+
+ dpbp_disable(&(dpbp_node->dpbp), CMD_PRI_LOW, dpbp_node->token);
+
+ if (h_bp_list == bp) {
+ h_bp_list = h_bp_list->next;
+ } else { /* if it is not the first node */
+ struct dpaa2_bp_list *prev = h_bp_list, *temp;
+ temp = h_bp_list->next;
+ while (temp) {
+ if (temp == bp) {
+ prev->next = temp->next;
+ free(bp);
+ break;
+ }
+ prev = temp;
+ temp = temp->next;
+ }
+ }
+
+ dpaa2_free_dpbp_dev(dpbp_node);
+}
+
+static
+void rte_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 rte_dpaa2_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 */
+ rte_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;
+ }
+ rte_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 = rte_dpaa2_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..c0e2411
--- /dev/null
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.h
@@ -0,0 +1,95 @@
+/*-
+ * 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 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 dpaa2_dpbp_dev *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 rte_dpaa2_bpid_info[MAX_BPID];
+
+int rte_dpaa2_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_pool_dpaa2_version.map b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
new file mode 100644
index 0000000..a8aa685
--- /dev/null
+++ b/drivers/pool/dpaa2/rte_pool_dpaa2_version.map
@@ -0,0 +1,8 @@
+DPDK_17.05 {
+ global:
+
+ rte_dpaa2_bpid_info;
+ rte_dpaa2_mbuf_alloc_bulk;
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 22c22d4..db5b790 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -109,6 +109,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pool_dpaa2
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
@ 2017-03-07 16:24 ` Ferruh Yigit
2017-03-08 9:05 ` Olivier MATZ
1 sibling, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-03-07 16:24 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Olivier MATZ, Hunt, David
On 3/3/2017 12:46 PM, Hemant Agrawal wrote:
> Adding NXP DPAA2 architecture specific mempool support.
>
> This patch also registers a dpaa2 type MEMPOOL OPS
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Cc'ing Olivier and Dave.
Hi Olivier, Dave,
Can you please help reviewing this patch?
Thanks,
ferruh
<...>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
2017-03-07 16:24 ` Ferruh Yigit
@ 2017-03-08 9:05 ` Olivier MATZ
2017-03-08 12:52 ` Hemant Agrawal
1 sibling, 1 reply; 549+ messages in thread
From: Olivier MATZ @ 2017-03-08 9:05 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, thomas.monjalon, bruce.richardson, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
Hi Hemant,
On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
<hemant.agrawal@nxp.com> wrote:
> Adding NXP DPAA2 architecture specific mempool support.
>
> This patch also registers a dpaa2 type MEMPOOL OPS
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> MAINTAINERS | 1 +
> config/common_base | 5 +
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +
> drivers/Makefile | 1 +
> drivers/pool/Makefile | 40 +++
> drivers/pool/dpaa2/Makefile | 72 ++++++
> drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339
> ++++++++++++++++++++++++++
> drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++++
> drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
I think the current mempool handlers should be moved first in a
separate patch.
I'd prefer drivers/mempool instead of drivers/pool (more precise and
more consistent with librte_mempool).
>
> [...]
>
> +
> +struct dpaa2_bp_info rte_dpaa2_bpid_info[MAX_BPID];
> +static struct dpaa2_bp_list *h_bp_list;
> +
> +static int
> +hw_mbuf_create_pool(struct rte_mempool *mp)
Would it work for something else than mbufs?
The initial approach of the mempool is to work for kind of object. The
specialization in mbuf is done by the mbuf layer.
> +{
> + struct dpaa2_bp_list *bp_list;
> + struct dpaa2_dpbp_dev *avail_dpbp;
> + struct dpbp_attr dpbp_attr;
> + uint32_t bpid;
> + int ret;
> +
> + avail_dpbp = dpaa2_alloc_dpbp_dev();
> +
> + if (!avail_dpbp) {
> + PMD_DRV_LOG(ERR, "DPAA2 resources not available");
> + return -1;
> + }
The other pool handlers return a -errno instead of -1. I think it
should be the same here.
The same comment can applies to other locations/functions.
> [...]
> +
> + /* 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;
> +
> +
> + rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
> + + rte_pktmbuf_priv_size(mp);
Are the 2 empty lines garbage?
> + rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
> + rte_dpaa2_bpid_info[bpid].bpid = bpid;
> +
> + mp->pool_data = (void *)&rte_dpaa2_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;
I think this flag should be declared in rte_mempool.h,
not in drivers/bus/fslmc/portal/dpaa2_hw_pvt.h.
It should also be documented, what does this flag mean?
> [...]
>
> +static
> +void rte_dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
> + void * const *obj_table,
> + uint32_t bpid,
> + uint32_t meta_data_size,
> + int count)
Is there a reason why some functions are prefixed with rte_dpaa2_ and
other but hw_mbuf_?
> +{
> + 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*/
bad spaces
> + for (i = 0; i < n ; i++)
> + bufs[i] = (uint64_t)obj_table[i] + meta_data_size;
> +
> + /* feed them to bman*/
missing space at the end
> + 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);
The while in not properly indented
> [...]
> +int rte_dpaa2_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 */
> + rte_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);
I think we should not assume the objects are mbufs.
But even if we do it, I don't see why we need to set the refcnt.
What is returned un buf[] table? In rte_dpaa2_mbuf_release(), it looks you
are using buf[i] = obj_table[i] + bp_info->meta_data_size
> [...]
> +
> +static unsigned
> +hw_mbuf_get_count(const struct rte_mempool *mp __rte_unused)
> +{
> + return 0;
Looks this is not implemented. This would give wrong mempool statistics
when calling rte_mempool_dump().
Adding a test for this handler in app/test may highlight these issues.
> [...]
> +
> +#define DPAA2_MAX_BUF_POOLS 8
> +
> +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
> + */
> +};
I think the usual doxygen comment in dpdk is "/**" instead of "/*!"
Regards,
Olivier
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-08 9:05 ` Olivier MATZ
@ 2017-03-08 12:52 ` Hemant Agrawal
2017-03-08 15:39 ` Thomas Monjalon
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-08 12:52 UTC (permalink / raw)
To: Olivier MATZ
Cc: dev, thomas.monjalon, bruce.richardson, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
Hi Olivier,
Thanks for your detailed review. Please see inline...
On 3/8/2017 2:35 PM, Olivier MATZ wrote:
> Hi Hemant,
>
> On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
> <hemant.agrawal@nxp.com> wrote:
>> Adding NXP DPAA2 architecture specific mempool support.
>>
>> This patch also registers a dpaa2 type MEMPOOL OPS
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>> MAINTAINERS | 1 +
>> config/common_base | 5 +
>> config/defconfig_arm64-dpaa2-linuxapp-gcc | 8 +
>> drivers/Makefile | 1 +
>> drivers/pool/Makefile | 40 +++
>> drivers/pool/dpaa2/Makefile | 72 ++++++
>> drivers/pool/dpaa2/dpaa2_hw_mempool.c | 339
>> ++++++++++++++++++++++++++
>> drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++++++++
>> drivers/pool/dpaa2/rte_pool_dpaa2_version.map | 8 +
>
> I think the current mempool handlers should be moved first in a
> separate patch.
>
Are you seeing any benefit by making it a separate patch series?
it will be difficult and tricky for us. The dpaa2_pool has a dependency
on mc bus patches. dpaa2_pmd has dependency on dpaa2_pool and mc buses.
This will mean that we have to split it into 3 patch series and it will
become cumbersome to deal with 3 series.
> I'd prefer drivers/mempool instead of drivers/pool (more precise and
> more consistent with librte_mempool).
>
We will take care of it in next revision.
>
>>
>> [...]
>>
>> +
>> +struct dpaa2_bp_info rte_dpaa2_bpid_info[MAX_BPID];
>> +static struct dpaa2_bp_list *h_bp_list;
>> +
>> +static int
>> +hw_mbuf_create_pool(struct rte_mempool *mp)
>
> Would it work for something else than mbufs?
> The initial approach of the mempool is to work for kind of object. The
> specialization in mbuf is done by the mbuf layer.
I think, we did discuss that hw offloaded mempool are mainly for packet
buffers/mbufs. Currently we only support mbuf type of objects.
Ideally a hw buffer pool can work for any kind mempool. However, it is
not the best way to use hw buffer pools. The latency to allocate buffers
are higher than software. The main advantage SoCs, get by using hw pool
is that they work seamlessly with the MAC layer.
>
>
>> +{
>> + struct dpaa2_bp_list *bp_list;
>> + struct dpaa2_dpbp_dev *avail_dpbp;
>> + struct dpbp_attr dpbp_attr;
>> + uint32_t bpid;
>> + int ret;
>> +
>> + avail_dpbp = dpaa2_alloc_dpbp_dev();
>> +
>> + if (!avail_dpbp) {
>> + PMD_DRV_LOG(ERR, "DPAA2 resources not available");
>> + return -1;
>> + }
>
> The other pool handlers return a -errno instead of -1. I think it
> should be the same here.
We will fix it.
>
> The same comment can applies to other locations/functions.
>
>> [...]
>> +
>> + /* 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;
>> +
>> +
>> + rte_dpaa2_bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
>> + + rte_pktmbuf_priv_size(mp);
>
> Are the 2 empty lines garbage?
we will fix it
>
>
>> + rte_dpaa2_bpid_info[bpid].bp_list = bp_list;
>> + rte_dpaa2_bpid_info[bpid].bpid = bpid;
>> +
>> + mp->pool_data = (void *)&rte_dpaa2_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;
>
> I think this flag should be declared in rte_mempool.h,
> not in drivers/bus/fslmc/portal/dpaa2_hw_pvt.h.
>
> It should also be documented, what does this flag mean?
Currently we need a way to differentiate that this is a hw allocated pkt
buffer pool or software based buffer pool. String comparison is costly.
This flag was discussed during the hw mempool patches of david. Not
everyone was in favor of keeping it in librte_mempool.
So, we just hid it inside our offloaded mempool.
>
>> [...]
>>
>> +static
>> +void rte_dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
>> + void * const *obj_table,
>> + uint32_t bpid,
>> + uint32_t meta_data_size,
>> + int count)
>
>
> Is there a reason why some functions are prefixed with rte_dpaa2_ and
> other but hw_mbuf_?
initial reason was to use rte_ only for exported functions. we can fix it.
>
>
>> +{
>> + 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*/
>
> bad spaces
ok
>
>> + for (i = 0; i < n ; i++)
>> + bufs[i] = (uint64_t)obj_table[i] + meta_data_size;
>> +
>> + /* feed them to bman*/
>
> missing space at the end
ok
>
>> + 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);
>
> The while in not properly indented
ok
>
>> [...]
>> +int rte_dpaa2_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 */
>> + rte_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);
>
> I think we should not assume the objects are mbufs.
currently we are only supporting packet buffer i.e. mbufs
> But even if we do it, I don't see why we need to set the refcnt.
rte_mbuf_raw_alloc has check.
RTE_ASSERT(rte_mbuf_refcnt_read(m) == 0);
So, mempool should have packets with refcnt as '0'.
In our case, during transmit the NIC releases the buffer back to the hw
pool without core intervention. We have no option to reset specific
fields of buffer in the hardware.
It can be set on per packet basis during transmission, but this will
than add to the packet processing cost. In case of simple forwarding,
NIC will directly get the packets from hw, it will release directly to
hw. So, we tried to avoid this cost in data path.
>
> What is returned un buf[] table? In rte_dpaa2_mbuf_release(), it looks you
> are using buf[i] = obj_table[i] + bp_info->meta_data_size
>
meta_data_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp);
In the hardware, we are configure address as buf, which is obj_table +
meta_data_size;
>
>> [...]
>> +
>> +static unsigned
>> +hw_mbuf_get_count(const struct rte_mempool *mp __rte_unused)
>> +{
>> + return 0;
>
> Looks this is not implemented. This would give wrong mempool statistics
> when calling rte_mempool_dump().
>
Now our MC buf supports the counts, so we can implement it in next version.
> Adding a test for this handler in app/test may highlight these issues.
Yes! we know it fails. It was not supported in our bus - objects earlier.
Thanks for the suggestion. We have a plan to add these test cases. We
will add it in our pending item list.
>
>
>> [...]
>> +
>> +#define DPAA2_MAX_BUF_POOLS 8
>> +
>> +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
>> + */
>> +};
>
> I think the usual doxygen comment in dpdk is "/**" instead of "/*!"
yes! we will fix it.
>
>
> Regards,
> Olivier
>
Regards,
Hemant
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-08 12:52 ` Hemant Agrawal
@ 2017-03-08 15:39 ` Thomas Monjalon
2017-03-09 5:57 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Thomas Monjalon @ 2017-03-08 15:39 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Olivier MATZ, dev, bruce.richardson, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
2017-03-08 18:22, Hemant Agrawal:
> > On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
> > <hemant.agrawal@nxp.com> wrote:
> > I think the current mempool handlers should be moved first in a
> > separate patch.
Yes it should have been done earlier.
> Are you seeing any benefit by making it a separate patch series?
A separate patchset for moving mempool handlers will be easy to review
and accept.
If integrated in this series, it is kind of hidden and prevent the
visibility and review it deserves.
By the way the mempool move should be directly committed in the main
repository, while this series targets next-net.
> it will be difficult and tricky for us. The dpaa2_pool has a dependency
> on mc bus patches. dpaa2_pmd has dependency on dpaa2_pool and mc buses.
You will just have to rebase this series on top of the new one.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-08 15:39 ` Thomas Monjalon
@ 2017-03-09 5:57 ` Hemant Agrawal
2017-03-14 6:42 ` Hemant Agrawal
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-09 5:57 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Olivier MATZ, dev, bruce.richardson, shreyansh.jain,
john.mcnamara, ferruh.yigit, jerin.jacob
On 3/8/2017 9:09 PM, Thomas Monjalon wrote:
> 2017-03-08 18:22, Hemant Agrawal:
>>> On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
>>> <hemant.agrawal@nxp.com> wrote:
>>> I think the current mempool handlers should be moved first in a
>>> separate patch.
>
> Yes it should have been done earlier.
>
>> Are you seeing any benefit by making it a separate patch series?
>
> A separate patchset for moving mempool handlers will be easy to review
> and accept.
> If integrated in this series, it is kind of hidden and prevent the
> visibility and review it deserves.
> By the way the mempool move should be directly committed in the main
> repository, while this series targets next-net.
>
hw mempool has dependency on mc-bus. So, we will break it into *5* series,
1. mc-bus - which can go on main repo - Rebased over main repo
2. dpaa2-pool - it can also go on main rep (depends on mc-bus) - Rebased
over 'main repo + 1'.
3. dpaa2-pmd - this depends on mc-bus and dpaa2-pool
A. mc-bus -another series rebased over net-next
B. dpaa2-pool - another series rebased over 'net-next + A'
C. the pmd itself rebased over 'net-next + A + B'
Are you sure, you will like us to do the above and flood the mailing
list :)
I think, this will make the review difficult.
Bruce, Ferruh, Olivier - does the above help you? If so, we can do it.
My preference is to keep it as it is. It can be applied on 'net-next' or
'main' as a whole. But I am open for suggestions.
>> it will be difficult and tricky for us. The dpaa2_pool has a dependency
>> on mc bus patches. dpaa2_pmd has dependency on dpaa2_pool and mc buses.
>
> You will just have to rebase this series on top of the new one.
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-09 5:57 ` Hemant Agrawal
@ 2017-03-14 6:42 ` Hemant Agrawal
2017-03-14 8:14 ` Olivier Matz
0 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-14 6:42 UTC (permalink / raw)
To: Thomas Monjalon, Olivier MATZ, bruce.richardson, ferruh.yigit
Cc: dev, shreyansh.jain, john.mcnamara, jerin.jacob
On 3/9/2017 11:27 AM, Hemant Agrawal wrote:
> On 3/8/2017 9:09 PM, Thomas Monjalon wrote:
>> 2017-03-08 18:22, Hemant Agrawal:
>>>> On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
>>>> <hemant.agrawal@nxp.com> wrote:
>>>> I think the current mempool handlers should be moved first in a
>>>> separate patch.
>>
>> Yes it should have been done earlier.
>>
>>> Are you seeing any benefit by making it a separate patch series?
>>
>> A separate patchset for moving mempool handlers will be easy to review
>> and accept.
>> If integrated in this series, it is kind of hidden and prevent the
>> visibility and review it deserves.
>> By the way the mempool move should be directly committed in the main
>> repository, while this series targets next-net.
>>
>
> hw mempool has dependency on mc-bus. So, we will break it into *5* series,
>
> 1. mc-bus - which can go on main repo - Rebased over main repo
> 2. dpaa2-pool - it can also go on main rep (depends on mc-bus) - Rebased
> over 'main repo + 1'.
> 3. dpaa2-pmd - this depends on mc-bus and dpaa2-pool
> A. mc-bus -another series rebased over net-next
> B. dpaa2-pool - another series rebased over 'net-next + A'
> C. the pmd itself rebased over 'net-next + A + B'
>
> Are you sure, you will like us to do the above and flood the mailing
> list :)
>
> I think, this will make the review difficult.
>
> Bruce, Ferruh, Olivier - does the above help you? If so, we can do it.
Any views, we can rebase our next version accordingly.
we are looking forward to get it merged in 17.05.
>
> My preference is to keep it as it is. It can be applied on 'net-next' or
> 'main' as a whole. But I am open for suggestions.
>
>>> it will be difficult and tricky for us. The dpaa2_pool has a dependency
>>> on mc bus patches. dpaa2_pmd has dependency on dpaa2_pool and mc buses.
>>
>> You will just have to rebase this series on top of the new one.
>>
>
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool
2017-03-14 6:42 ` Hemant Agrawal
@ 2017-03-14 8:14 ` Olivier Matz
0 siblings, 0 replies; 549+ messages in thread
From: Olivier Matz @ 2017-03-14 8:14 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Thomas Monjalon, bruce.richardson, ferruh.yigit, dev,
shreyansh.jain, john.mcnamara, jerin.jacob
Hi Hemant,
On Tue, 14 Mar 2017 12:12:17 +0530, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
> On 3/9/2017 11:27 AM, Hemant Agrawal wrote:
> > On 3/8/2017 9:09 PM, Thomas Monjalon wrote:
> >> 2017-03-08 18:22, Hemant Agrawal:
> >>>> On Fri, 3 Mar 2017 18:16:36 +0530, Hemant Agrawal
> >>>> <hemant.agrawal@nxp.com> wrote:
> >>>> I think the current mempool handlers should be moved first in a
> >>>> separate patch.
> >>
> >> Yes it should have been done earlier.
> >>
> >>> Are you seeing any benefit by making it a separate patch series?
> >>
> >> A separate patchset for moving mempool handlers will be easy to review
> >> and accept.
> >> If integrated in this series, it is kind of hidden and prevent the
> >> visibility and review it deserves.
> >> By the way the mempool move should be directly committed in the main
> >> repository, while this series targets next-net.
> >>
> >
> > hw mempool has dependency on mc-bus. So, we will break it into *5* series,
> >
> > 1. mc-bus - which can go on main repo - Rebased over main repo
> > 2. dpaa2-pool - it can also go on main rep (depends on mc-bus) - Rebased
> > over 'main repo + 1'.
> > 3. dpaa2-pmd - this depends on mc-bus and dpaa2-pool
> > A. mc-bus -another series rebased over net-next
> > B. dpaa2-pool - another series rebased over 'net-next + A'
> > C. the pmd itself rebased over 'net-next + A + B'
> >
> > Are you sure, you will like us to do the above and flood the mailing
> > list :)
> >
> > I think, this will make the review difficult.
> >
> > Bruce, Ferruh, Olivier - does the above help you? If so, we can do it.
>
> Any views, we can rebase our next version accordingly.
> we are looking forward to get it merged in 17.05.
Yes, moving the other mempool drivers in the drivers/ directory
before adding another one there makes sense to me, in order to
avoid having two places for mempool handlers.
As Thomas stated, it's probably better to have it in another
patchset, so it can be quickly reviewed and integrated.
Regards,
Olivier
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 20/46] bus/fslmc: affine dpio to crypto threads
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (18 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 19/46] pool/dpaa2: add DPAA2 hardware offloaded mempool Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 21/46] bus/fslmc: define queues for DPAA2 devices Hemant Agrawal
` (28 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 45 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 3 ++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
3 files changed, 49 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index dd6de4c..bd1f643 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index 682f3fa..b1a1b8f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -56,5 +56,8 @@ 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);
+
#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 66840b1..0c3f3c2 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -2,6 +2,7 @@ DPDK_17.05 {
global:
dpaa2_affine_qbman_swp;
+ dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
dpaa2_free_dpbp_dev;
dpbp_disable;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 21/46] bus/fslmc: define queues for DPAA2 devices
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (19 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 20/46] bus/fslmc: affine dpio to crypto threads Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 22/46] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (27 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Before DPAA2 devices can communicate using hardware queues, this patch
adds queue definitions in the FSLMC bus which the DPAA2 devices would
instantitate.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index ad2847f..42c5517 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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 */
@@ -79,6 +82,23 @@ struct dpaa2_dpbp_dev {
uint32_t dpbp_id; /*HW ID for DPBP object */
};
+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 *(*rte_mcp_ptr_list);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 22/46] net/dpaa2: adding eth ops to dpaa2
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (20 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 21/46] bus/fslmc: define queues for DPAA2 devices Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 23/46] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (26 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 426 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index db94b45..4f78565 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -50,6 +50,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
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 ead6a2c..934755a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 23/46] net/dpaa2: add RSS flow distribution
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (21 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 22/46] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 24/46] net/dpaa2: configure MAC address at init Hemant Agrawal
` (25 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 4f78565..b5f3ebb 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -59,6 +59,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
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 934755a..c14b4df 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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;
priv->hw = dpni_dev;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 24/46] net/dpaa2: configure MAC address at init
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (22 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 23/46] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 25/46] bus/fslmc: define hardware annotation area size Hemant Agrawal
` (24 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 c14b4df..ab9dfe6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -443,6 +444,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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 25/46] bus/fslmc: define hardware annotation area size
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (23 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 24/46] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 26/46] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (23 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 42c5517..8efac2d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 26/46] net/dpaa2: attach the buffer pool to dpni
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (24 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 25/46] bus/fslmc: define hardware annotation area size Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 27/46] bus/fslmc: introduce true and false macros Hemant Agrawal
` (22 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/net/dpaa2/Makefile | 4 +++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 57 +++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 62 ++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 6 ++++
4 files changed, 129 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index b5f3ebb..086c76e 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -51,6 +51,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
+CFLAGS += -I$(RTE_SDK)/drivers/pool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -65,8 +66,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/pool/dpaa2
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_pool_dpaa2
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 ab9dfe6..906a4d9 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -475,6 +488,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 27/46] bus/fslmc: introduce true and false macros
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (25 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 26/46] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 28/46] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (21 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 8efac2d..1af93a5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 28/46] net/dpaa2: add support for L3 and L4 checksum offload
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (26 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 27/46] bus/fslmc: introduce true and false macros Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 29/46] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (20 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 906a4d9..763c574 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 29/46] net/dpaa2: add support for promiscuous mode
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (27 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 28/46] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 30/46] bus/fslmc: define VLAN header length Hemant Agrawal
` (19 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 763c574..05c7e94 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 30/46] bus/fslmc: define VLAN header length
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (28 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 29/46] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 31/46] net/dpaa2: add MTU configuration support Hemant Agrawal
` (18 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1af93a5..2a8d9e5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 31/46] net/dpaa2: add MTU configuration support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (29 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 30/46] bus/fslmc: define VLAN header length Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 32/46] bus/fslmc: add packet FLE definitions Hemant Agrawal
` (17 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 05c7e94..53987cf 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 32/46] bus/fslmc: add packet FLE definitions
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (30 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 31/46] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 33/46] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (16 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 53 +++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 2a8d9e5..c26360d3 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/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*/
@@ -122,6 +128,53 @@ struct dpaa2_queue {
/*! Global MCP list */
extern void *(*rte_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
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 33/46] net/dpaa2: enable packet Rx and Tx operations
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (31 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 32/46] bus/fslmc: add packet FLE definitions Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 34/46] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (15 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 086c76e..21f0849 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -61,6 +61,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 53987cf..93ca0fa 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 34/46] net/dpaa2: support for Rx packet parsing and packet type
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (32 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 33/46] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 35/46] net/dpaa2: link status update Hemant Agrawal
` (14 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 93ca0fa..c4131e1 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 35/46] net/dpaa2: link status update
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (33 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 34/46] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 36/46] net/dpaa2: basic stats support Hemant Agrawal
` (13 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 c4131e1..14b9654 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 36/46] net/dpaa2: basic stats support
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (34 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 35/46] net/dpaa2: link status update Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 37/46] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (12 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 14b9654..1d6ae36 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 37/46] net/dpaa2: enable stashing for LS2088A devices
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (35 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 36/46] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 38/46] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (11 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 1d6ae36..64f41d9 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 38/46] net/dpaa2: handle non-hardware backed buffer pool
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (36 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 37/46] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 39/46] bus/fslmc: add physical-virtual address translation helpers Hemant Agrawal
` (10 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..a94761c 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_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),
+ rte_dpaa2_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 +380,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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 39/46] bus/fslmc: add physical-virtual address translation helpers
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (37 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 38/46] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 40/46] pool/dpaa2: enable physical addressing for pool buffers Hemant Agrawal
` (9 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 66 +++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index c26360d3..ad8a22f 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -175,6 +175,72 @@ 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 */
+
struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void);
void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 40/46] pool/dpaa2: enable physical addressing for pool buffers
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (38 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 39/46] bus/fslmc: add physical-virtual address translation helpers Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 41/46] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (8 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/pool/dpaa2/dpaa2_hw_mempool.c b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
index 0c8de51..ca42418 100644
--- a/drivers/pool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/pool/dpaa2/dpaa2_hw_mempool.c
@@ -203,9 +203,14 @@ void rte_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);
@@ -214,8 +219,15 @@ void rte_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,
@@ -288,6 +300,7 @@ int rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 41/46] net/dpaa2: enable physical addressing for packet buffers
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (39 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 40/46] pool/dpaa2: enable physical addressing for pool buffers Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 42/46] config: add configuration for toggling physical addressing Hemant Agrawal
` (7 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 a94761c..49b4558 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 42/46] config: add configuration for toggling physical addressing
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (40 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 41/46] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-03-03 12:46 ` Hemant Agrawal
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 43/46] bus/fslmc: add support for DMA mapping for ARM SMMU Hemant Agrawal
` (6 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:46 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index c07a95e..263657e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -290,6 +290,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
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 3cdb31b..29a56c7 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 43/46] bus/fslmc: add support for DMA mapping for ARM SMMU
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (41 preceding siblings ...)
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 42/46] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-03-03 12:47 ` Hemant Agrawal
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 44/46] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (5 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:47 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 96 +++++++++++++++++++++++++++++
drivers/bus/fslmc/fslmc_vfio.h | 1 +
drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 +
3 files changed, 98 insertions(+)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index fc017fc..5f1d1b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -76,8 +76,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 *(*rte_mcp_ptr_list);
static uint32_t mcp_id;
+static int is_dma_done;
static int vfio_connect_container(struct fslmc_vfio_group *vfio_group)
{
@@ -147,6 +149,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,71 @@ int vfio_dmamap_mem_region(uint64_t vaddr,
return 0;
}
+int rte_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 80c6869..53dd0b7 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -70,6 +70,7 @@ int vfio_dmamap_mem_region(
int fslmc_vfio_setup_group(void);
int fslmc_vfio_process_group(void);
+int rte_fslmc_vfio_dmamap(void);
/* create dpio device */
int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev,
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 0c3f3c2..e357435 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -40,6 +40,7 @@ DPDK_17.05 {
qbman_swp_send_multiple;
rte_fslmc_driver_register;
rte_fslmc_driver_unregister;
+ rte_fslmc_vfio_dmamap;
rte_mcp_ptr_list;
local: *;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 44/46] net/dpaa2: enable DMA Mapping during device scanning
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (42 preceding siblings ...)
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 43/46] bus/fslmc: add support for DMA mapping for ARM SMMU Hemant Agrawal
@ 2017-03-03 12:47 ` Hemant Agrawal
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 45/46] bus/fslmc: frame queue based dq storage alloc Hemant Agrawal
` (4 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:47 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 64f41d9..6dddc3b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 45/46] bus/fslmc: frame queue based dq storage alloc
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (43 preceding siblings ...)
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 44/46] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-03-03 12:47 ` Hemant Agrawal
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 46/46] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
` (3 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:47 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/bus/fslmc/portal/dpaa2_hw_dpio.c | 32 +++++++++++++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 7 +++++++
drivers/bus/fslmc/rte_bus_fslmc_version.map | 2 ++
3 files changed, 41 insertions(+)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index bd1f643..c80d6c5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/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/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index b1a1b8f..f2e1168 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -59,5 +59,12 @@ struct dpaa2_io_portal_t {
/* Affine additional DPIO portal to current crypto processing thread */
int dpaa2_affine_qbman_swp_sec(void);
+/* 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/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index e357435..97d6b15 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -4,7 +4,9 @@ DPDK_17.05 {
dpaa2_affine_qbman_swp;
dpaa2_affine_qbman_swp_sec;
dpaa2_alloc_dpbp_dev;
+ dpaa2_alloc_dq_storage;
dpaa2_free_dpbp_dev;
+ dpaa2_free_dq_storage;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCHv8 46/46] net/dpaa2: enable frame queue based dequeuing
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (44 preceding siblings ...)
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 45/46] bus/fslmc: frame queue based dq storage alloc Hemant Agrawal
@ 2017-03-03 12:47 ` Hemant Agrawal
2017-03-07 16:13 ` [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD Thomas Monjalon
` (2 subsequent siblings)
48 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-03 12:47 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 6dddc3b..c6ee406 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (45 preceding siblings ...)
2017-03-03 12:47 ` [dpdk-dev] [PATCHv8 46/46] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-03-07 16:13 ` Thomas Monjalon
2017-03-07 17:00 ` Ferruh Yigit
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
48 siblings, 0 replies; 549+ messages in thread
From: Thomas Monjalon @ 2017-03-07 16:13 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
2017-03-03 18:16, Hemant Agrawal:
> v8:
> * rebased over master (17.02: 35b09d76)
> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
Looks to be the best place for these libraries (except outside of DPDK ;)
Thanks for having moved them in the bus sub-directory.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (46 preceding siblings ...)
2017-03-07 16:13 ` [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD Thomas Monjalon
@ 2017-03-07 17:00 ` Ferruh Yigit
2017-03-08 12:30 ` Shreyansh Jain
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
48 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-03-07 17:00 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob, Jan Blunck
On 3/3/2017 12:46 PM, Hemant Agrawal wrote:
> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> fsl-mc bus driver and network SoC PMD. This version of the driver
> supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
>
> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> designed for high-speed network packet processing. It uses a bus name
> ‘fsl-mc’, part of Linux Kernel Staging tree [1], for resource management.
>
> A brief description of architecture is given below; detailed description
> is part of the documentation in the patches itself.
>
> DPAA2 contains hardware component called the Management Complex (or MC).
> It manages the DPAA2 hardware resources. The MC provides an object-based
> abstraction for software drivers to use the DPAA2 hardware.
>
> Some of the key objects are:
> - DPNI, which refers to the network interface object.
> - DPBP, which refers to HW based memory pool object
> - DPIO, refers to processing context for accessing QBMAN
>
> Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
> called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
> software/user-space to the queues and buffers implemented in the hardware.
>
> The patch series could be logically structured into following sub-areas:
> 1. Make file changes for crc in armv8 core machine type and driver dependency
> 2. Indroducing fsl-mc bus as rte_bus, it's componenets.
> 3. Introducing dpaa2 pmd driver
> 4. Introducing dpaa2 mempool
> 5. Support for DPAA2 Ethernet Device (ethdev)
> 6. Additional functionality in DPAA2 ethdev.
>
> The following design decisions are made during development:
>
> 1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator drivers.
> These drivers will be shared with dpaa2 based crypto drivers.
>
> 2. DPAA2 implements the HW mempool offload with DPBP object.
> - The new pool is being configured using compile time option and pool name
> as "dpaa2".
>
> 3. It maintains per lcore DPIO objects and affine the DPIO instance to the
> processing threads accessing the QBMAN HW.
>
> Prerequisites:
> - For running the PMD, NXP's SoC (board) is required.
> Information about obtaining relevant software is available in the docs
> as part of the patch.
>
> Future Changes/Caveats:
>
> 1. VFIO code for fsl-mc bus is different than eal-vfio code for pci bus.
> This need to be re-worked to make possible re-use of the existing code.
>
>
> References:
> [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
>
> ---
> v8:
> * rebased over master (17.02: 35b09d76)
> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
> * Updated documentation to remove non-open source dependency
> * Reduced shared symbols in map files
>
> v7:
> * rebased over master (17.02)
> * fix the shared lib compilation
> * re partitiion the patches as per Ferruh comments.
> * handling Ferruh's comment for NXP dpaa2 driver
>
> v6:
> * rebased over master (61207d0)
> * removing DPAA2_COMMON as configurable option
> * renaming drivers bus, pool libraries removing 'pmd'
> * Headers of Licenses
> * exposed variable renaming with *rte_* prefix
> * handling Ferruh's comment for NXP dpaa2 driver
> * moving around MAINTAINER and DOC file patches
>
> v5:
> * rebased over master (6818a7f4)
>
> v4:
> * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
>
> v3:
> * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
> * Fixed comment from John on Patch-0003 for documentation
> * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
> another series
>
> v2:
> * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
> * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
> * removed documentation warnings and missing information.
> * removed arm64 part specific code from driver
> * changed rte_panic to errors
> * reduced checkpatch warnings
>
>
> Hemant Agrawal (45):
> mk/dpaa2: add the crc support to the machine type
> bus/fslmc: introducing fsl-mc bus driver
> bus/fslmc: add QBMAN driver to bus
> bus/fslmc: introduce MC object functions
> bus/fslmc: add mc dpio object support
> bus/fslmc: add mc dpbp object support
> eal/vfio: adding vfio utility functions in map file
> bus/fslmc: add vfio support
> bus/fslmc: scan for net and sec device
> net/dpaa2: introducing NXP DPAA2 PMD driver
> doc: add DPAA2 NIC details
> bus/fslmc: add debug log support
> net/dpaa2: add debug log support
> config: enable support for DPAA2 debug logging
> net/dpaa2: add mc dpni object support
> bus/fslmc: dpio portal driver
> bus/fslmc: introduce support for hw mempool object
> pool/dpaa2: add DPAA2 hardware offloaded mempool
> bus/fslmc: affine dpio to crypto threads
> bus/fslmc: define queues for DPAA2 devices
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add RSS flow distribution
> net/dpaa2: configure MAC address at init
> bus/fslmc: define hardware annotation area size
> net/dpaa2: attach the buffer pool to dpni
> bus/fslmc: introduce true and false macros
> net/dpaa2: add support for L3 and L4 checksum offload
> net/dpaa2: add support for promiscuous mode
> bus/fslmc: define VLAN header length
> net/dpaa2: add MTU configuration support
> bus/fslmc: add packet FLE definitions
> net/dpaa2: enable packet Rx and Tx operations
> net/dpaa2: support for Rx packet parsing and packet type
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: handle non-hardware backed buffer pool
> bus/fslmc: add physical-virtual address translation helpers
> pool/dpaa2: enable physical addressing for pool buffers
> net/dpaa2: enable physical addressing for packet buffers
> config: add configuration for toggling physical addressing
> bus/fslmc: add support for DMA mapping for ARM SMMU
> net/dpaa2: enable DMA Mapping during device scanning
> bus/fslmc: frame queue based dq storage alloc
> net/dpaa2: enable frame queue based dequeuing
>
> Shreyansh Jain (1):
> mk: handle intra drivers dependencies for shared build
Hi Hemant,
Did you able to find a chance to check Jan Blunck's eth_driver [1]
patchset. I remember in previous versions of this patchset there was a
eth_driver update too.
Perhaps dpaa2 can benefit from those updates?
Thanks,
ferruh
[1]
http://dpdk.org/ml/archives/dev/2017-March/059376.html
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCHv8 00/46] NXP DPAA2 PMD
2017-03-07 17:00 ` Ferruh Yigit
@ 2017-03-08 12:30 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-03-08 12:30 UTC (permalink / raw)
To: Ferruh Yigit, Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, john.mcnamara, jerin.jacob,
Jan Blunck
Hello Ferruh,
> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Tuesday, March 07, 2017 10:31 PM
> To: Hemant Agrawal <hemant.agrawal@nxp.com>; dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com;
> jerin.jacob@caviumnetworks.com; Jan Blunck <jblunck@infradead.org>
> Subject: Re: [PATCHv8 00/46] NXP DPAA2 PMD
>
[...]
> > net/dpaa2: enable frame queue based dequeuing
> >
> > Shreyansh Jain (1):
> > mk: handle intra drivers dependencies for shared build
>
> Hi Hemant,
>
> Did you able to find a chance to check Jan Blunck's eth_driver [1]
> patchset. I remember in previous versions of this patchset there was a
> eth_driver update too.
Thanks for highlighting.
Yes, I had a look at that patchset a couple of days back.
In case of DPAA2 PMD, we are not actually using eth_driver. There is a dummy reference that we are creating which can easily be removed. We were doing only to be 'similar' to other existing PMDs.
In fact, I will go ahead and remove this use of eth_driver instance in v9 (considering there are some comments from Olivier which too need changes).
>
> Perhaps dpaa2 can benefit from those updates?
So, that patchset is positive for us, but doesn't really impact the existing patches (functionally).
>
> Thanks,
> ferruh
>
> [1]
> http://dpdk.org/ml/archives/dev/2017-March/059376.html
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD
2017-03-03 12:46 ` [dpdk-dev] [PATCHv8 00/46] " Hemant Agrawal
` (47 preceding siblings ...)
2017-03-07 17:00 ` Ferruh Yigit
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (23 more replies)
48 siblings, 24 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
(This patches has been split from DPAA2 PMD v8 series [2] as per
comments received on ML [3].)
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
network SoC PMD. This version of the driver supports NXP LS208xA,
LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
Dependency:
This patchset is to be applied over
a) NXP DPAA2 FSLMC Bus Patches [4] and
b) NXP DPAA2 Mempool patches [5]
Prerequisites:
- For running the PMD, NXP's SoC (board) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
[3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
[4] http://dpdk.org/ml/archives/dev/2017-March/060453.html
[5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
---
v9:
* Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
* Rebased over master (17.02, 630f6ec1)
* remove the eth_driver usages
v8:
* rebased over master (17.02: 35b09d76)
* Removed all drivers/common/* code and moved to drivers/bus/fslmc
* Updated documentation to remove non-open source dependency
* Reduced shared symbols in map files
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (22):
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
net/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
net/dpaa2: add mc dpni object support
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add MTU configuration support
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
net/dpaa2: enable DMA Mapping during device scanning
net/dpaa2: enable frame queue based dequeuing
MAINTAINERS | 3 +
config/common_base | 11 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 11 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 77 ++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 ++++++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1036 ++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 +++++++++
drivers/net/dpaa2/mc/dpni.c | 739 ++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 ++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 +++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 +++++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 +
21 files changed, 5860 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 02/22] doc: add DPAA2 NIC details Hemant Agrawal
` (22 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 2 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 61 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 138 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 ++
9 files changed, 266 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/MAINTAINERS b/MAINTAINERS
index 229b919..1b1e1d7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -351,8 +351,10 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index 1c3bbe0..8ec3591 100644
--- a/config/common_base
+++ b/config/common_base
@@ -302,6 +302,11 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 47a5eee..487ed7e 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -54,3 +54,8 @@ CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
# 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/net/Makefile b/drivers/net/Makefile
index a16f25e..487b917 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
DIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
@@ -56,7 +57,6 @@ 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
-
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..4f5dbf7
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,61 @@
+# 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/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+
+LDLIBS += -lrte_bus_fslmc
+
+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..79ee08d
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,138 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ 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");
+ rte_eth_dev_release_port(eth_dev);
+ return -ENOMEM;
+ }
+ }
+ eth_dev->device = &dpaa2_dev->device;
+ dpaa2_dev->eth_dev = eth_dev;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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..8591cc0
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.05 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0e0b600..79320e6 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -108,6 +108,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_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
@@ -150,6 +151,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += -L$(ARMV8_CRYPTO_LIB_PATH) -
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += -lrte_pmd_crypto_scheduler
endif # CONFIG_RTE_LIBRTE_CRYPTODEV
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_mempool_dpaa2
+endif # CONFIG_RTE_LIBRTE_DPAA2_PMD
+
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
_LDLIBS-y += --no-whole-archive
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 02/22] doc: add DPAA2 NIC details
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-24 15:35 ` Ferruh Yigit
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 03/22] net/dpaa2: add debug log support Hemant Agrawal
` (21 subsequent siblings)
23 siblings, 1 reply; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 12 +-
5 files changed, 636 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index 1b1e1d7..4108266 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -355,6 +355,7 @@ M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..7d7a6c5
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,614 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+ For example, the *aarch64* Linaro Toolchain, which can be obtained from
+ `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+
+2. **Linux Kernel**
+
+ It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+ Any *aarch64* supporting filesystem can be used. For example,
+ Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+ from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+As an alternative method, DPAA2 PMD can also be executed using images provided
+as part of SDK from NXP. The SDK includes all the above prerequisites necessary
+to bring up a DPAA2 board.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 87f9334..be21e8a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 357965a..a27f6b7 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -15,7 +15,6 @@ DPDK Release 17.02
firefox build/doc/html/guides/rel_notes/release_17_02.html
-
New Features
------------
@@ -250,6 +249,17 @@ New Features
See the :ref:`Elastic Flow Distributor Library <Efd_Library>` documentation in
the Programmers Guide document, for more information.
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
Resolved Issues
---------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v9 02/22] doc: add DPAA2 NIC details
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-03-24 15:35 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-03-24 15:35 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 3/17/2017 1:08 PM, Hemant Agrawal wrote:
> This patch adds the NXP dpaa2 architecture and pmd details
> in the Network interfaces section.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Acked-by: John McNamara <john.mcnamara@intel.com>
> ---
> MAINTAINERS | 1 +
> doc/guides/nics/dpaa2.rst | 614 +++++++++++++++++++++++++++++++++
I am getting following warning [1] while building docs, not sure about
the reason. Can you please check it?
[1]
.../doc/guides/nics/dpaa2.rst:32: WARNING: Duplicate explicit target
name: "here".
Thanks,
ferruh
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 03/22] net/dpaa2: add debug log support
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
` (20 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 4f5dbf7..3e3c8d1 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 79ee08d..c2dffbb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -92,8 +97,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 04/22] config: enable support for DPAA2 debug logging
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (2 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 03/22] net/dpaa2: add debug log support Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
` (19 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 8ec3591..1c54777 100644
--- a/config/common_base
+++ b/config/common_base
@@ -305,6 +305,11 @@ 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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 487ed7e..a7d305a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -59,3 +59,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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 05/22] net/dpaa2: add mc dpni object support
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (3 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (18 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 4 +
drivers/net/dpaa2/mc/dpni.c | 739 +++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 ++++++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 ++++++++++++++
6 files changed, 2965 insertions(+)
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 3e3c8d1..db94b45 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -43,10 +43,13 @@ else
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
endif
+CFLAGS += "-Wno-strict-aliasing"
CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -56,6 +59,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/net/dpaa2/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/dpaa2/mc/fsl_dpkg.h b/drivers/net/dpaa2/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 06/22] net/dpaa2: adding eth ops to dpaa2
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (4 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (17 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 426 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index db94b45..4f78565 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -50,6 +50,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
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 c2dffbb..ef826fb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 07/22] net/dpaa2: add RSS flow distribution
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (5 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
` (16 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 4f78565..b5f3ebb 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -59,6 +59,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
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 ef826fb..266f70b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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;
priv->hw = dpni_dev;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 08/22] net/dpaa2: configure MAC address at init
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (6 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (15 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 266f70b..47a8788 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -443,6 +444,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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 09/22] net/dpaa2: attach the buffer pool to dpni
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (7 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (14 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/net/dpaa2/Makefile | 4 +++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 57 +++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 62 ++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 6 ++++
4 files changed, 129 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index b5f3ebb..e7862f1 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -51,6 +51,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
+CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -65,8 +66,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/mempool/dpaa2
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_mempool_dpaa2
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 47a8788..60e984b 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -475,6 +488,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 10/22] net/dpaa2: add support for L3 and L4 checksum offload
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (8 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (13 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 60e984b..f517355 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 11/22] net/dpaa2: add support for promiscuous mode
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (9 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
` (12 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 f517355..c4557d6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 12/22] net/dpaa2: add MTU configuration support
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (10 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (11 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c4557d6..70c8701 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 13/22] net/dpaa2: enable packet Rx and Tx operations
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (11 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (10 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index e7862f1..cb3bccf 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -61,6 +61,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 70c8701..9c4b185 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 14/22] net/dpaa2: support for Rx packet parsing and packet type
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (12 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 15/22] net/dpaa2: link status update Hemant Agrawal
` (9 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 9c4b185..816227b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 15/22] net/dpaa2: link status update
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (13 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 16/22] net/dpaa2: basic stats support Hemant Agrawal
` (8 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 816227b..db4691c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 16/22] net/dpaa2: basic stats support
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (14 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 15/22] net/dpaa2: link status update Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (7 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 db4691c..9a60777 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 17/22] net/dpaa2: enable stashing for LS2088A devices
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (15 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 16/22] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (6 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 9a60777..16baaf0 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 18/22] net/dpaa2: handle non-hardware backed buffer pool
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (16 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (5 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..a94761c 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_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),
+ rte_dpaa2_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 +380,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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 19/22] net/dpaa2: enable physical addressing for packet buffers
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (17 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
` (4 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 a94761c..49b4558 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 20/22] config: add configuration for toggling physical addressing
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (18 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (3 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index 1c54777..4c3674e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -295,6 +295,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 a7d305a..6b3f3cc 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile NXP DPAA2 FSL-MC Bus
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 21/22] net/dpaa2: enable DMA Mapping during device scanning
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (19 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
` (2 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 16baaf0..6d291be 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v9 22/22] net/dpaa2: enable frame queue based dequeuing
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (20 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-03-17 13:08 ` Hemant Agrawal
2017-03-23 14:34 ` [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD Ferruh Yigit
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-17 13:08 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 6d291be..dc83815 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (21 preceding siblings ...)
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-03-23 14:34 ` Ferruh Yigit
2017-03-23 16:59 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
23 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-03-23 14:34 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 3/17/2017 1:08 PM, Hemant Agrawal wrote:
> (This patches has been split from DPAA2 PMD v8 series [2] as per
> comments received on ML [3].)
>
> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> network SoC PMD. This version of the driver supports NXP LS208xA,
> LS204xA and LS108x families Network SoCs.
>
> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> designed for high-speed network packet processing. It uses a bus name
> ‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
>
> Dependency:
> This patchset is to be applied over
> a) NXP DPAA2 FSLMC Bus Patches [4] and
> b) NXP DPAA2 Mempool patches [5]
>
> Prerequisites:
> - For running the PMD, NXP's SoC (board) is required.
> Information about obtaining relevant software is available in the docs
> as part of the patch.
>
> References:
> [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
> [2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
> [3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
> [4] http://dpdk.org/ml/archives/dev/2017-March/060453.html
> [5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
>
> ---
> v9:
> * Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
> * Rebased over master (17.02, 630f6ec1)
> * remove the eth_driver usages
>
> v8:
> * rebased over master (17.02: 35b09d76)
> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
> * Updated documentation to remove non-open source dependency
> * Reduced shared symbols in map files
>
> v7:
> * rebased over master (17.02)
> * fix the shared lib compilation
> * re partitiion the patches as per Ferruh comments.
> * handling Ferruh's comment for NXP dpaa2 driver
>
> v6:
> * rebased over master (61207d0)
> * removing DPAA2_COMMON as configurable option
> * renaming drivers bus, pool libraries removing 'pmd'
> * Headers of Licenses
> * exposed variable renaming with *rte_* prefix
> * handling Ferruh's comment for NXP dpaa2 driver
> * moving around MAINTAINER and DOC file patches
>
> v5:
> * rebased over master (6818a7f4)
>
> v4:
> * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
>
> v3:
> * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
> * Fixed comment from John on Patch-0003 for documentation
> * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
> another series
>
> v2:
> * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
> * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
> * removed documentation warnings and missing information.
> * removed arm64 part specific code from driver
> * changed rte_panic to errors
> * reduced checkpatch warnings
>
> Hemant Agrawal (22):
> net/dpaa2: introducing NXP DPAA2 PMD driver
> doc: add DPAA2 NIC details
> net/dpaa2: add debug log support
> config: enable support for DPAA2 debug logging
> net/dpaa2: add mc dpni object support
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add RSS flow distribution
> net/dpaa2: configure MAC address at init
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for L3 and L4 checksum offload
> net/dpaa2: add support for promiscuous mode
> net/dpaa2: add MTU configuration support
> net/dpaa2: enable packet Rx and Tx operations
> net/dpaa2: support for Rx packet parsing and packet type
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: handle non-hardware backed buffer pool
> net/dpaa2: enable physical addressing for packet buffers
> config: add configuration for toggling physical addressing
> net/dpaa2: enable DMA Mapping during device scanning
> net/dpaa2: enable frame queue based dequeuing
Hi Hemant, Shreyansh,
Can you please rebase the patchset on top of latest next-net, I am
getting some merge conflics.
Also patchset should update release_17_05.rst, instead of release_17_02.rst.
Thanks,
ferruh
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD
2017-03-23 14:34 ` [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD Ferruh Yigit
@ 2017-03-23 16:59 ` Hemant Agrawal
0 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-23 16:59 UTC (permalink / raw)
To: Ferruh Yigit, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 3/23/2017 8:04 PM, Ferruh Yigit wrote:
> On 3/17/2017 1:08 PM, Hemant Agrawal wrote:
>> (This patches has been split from DPAA2 PMD v8 series [2] as per
>> comments received on ML [3].)
>>
>> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
>> network SoC PMD. This version of the driver supports NXP LS208xA,
>> LS204xA and LS108x families Network SoCs.
>>
>> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
>> designed for high-speed network packet processing. It uses a bus name
>> ‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
>>
>> Dependency:
>> This patchset is to be applied over
>> a) NXP DPAA2 FSLMC Bus Patches [4] and
>> b) NXP DPAA2 Mempool patches [5]
>>
>> Prerequisites:
>> - For running the PMD, NXP's SoC (board) is required.
>> Information about obtaining relevant software is available in the docs
>> as part of the patch.
>>
>> References:
>> [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
>> [2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
>> [3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
>> [4] http://dpdk.org/ml/archives/dev/2017-March/060453.html
>> [5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
>>
>> ---
>> v9:
>> * Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
>> * Rebased over master (17.02, 630f6ec1)
>> * remove the eth_driver usages
>>
>> v8:
>> * rebased over master (17.02: 35b09d76)
>> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
>> * Updated documentation to remove non-open source dependency
>> * Reduced shared symbols in map files
>>
>> v7:
>> * rebased over master (17.02)
>> * fix the shared lib compilation
>> * re partitiion the patches as per Ferruh comments.
>> * handling Ferruh's comment for NXP dpaa2 driver
>>
>> v6:
>> * rebased over master (61207d0)
>> * removing DPAA2_COMMON as configurable option
>> * renaming drivers bus, pool libraries removing 'pmd'
>> * Headers of Licenses
>> * exposed variable renaming with *rte_* prefix
>> * handling Ferruh's comment for NXP dpaa2 driver
>> * moving around MAINTAINER and DOC file patches
>>
>> v5:
>> * rebased over master (6818a7f4)
>>
>> v4:
>> * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
>>
>> v3:
>> * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
>> * Fixed comment from John on Patch-0003 for documentation
>> * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
>> another series
>>
>> v2:
>> * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
>> * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
>> * removed documentation warnings and missing information.
>> * removed arm64 part specific code from driver
>> * changed rte_panic to errors
>> * reduced checkpatch warnings
>>
>> Hemant Agrawal (22):
>> net/dpaa2: introducing NXP DPAA2 PMD driver
>> doc: add DPAA2 NIC details
>> net/dpaa2: add debug log support
>> config: enable support for DPAA2 debug logging
>> net/dpaa2: add mc dpni object support
>> net/dpaa2: adding eth ops to dpaa2
>> net/dpaa2: add RSS flow distribution
>> net/dpaa2: configure MAC address at init
>> net/dpaa2: attach the buffer pool to dpni
>> net/dpaa2: add support for L3 and L4 checksum offload
>> net/dpaa2: add support for promiscuous mode
>> net/dpaa2: add MTU configuration support
>> net/dpaa2: enable packet Rx and Tx operations
>> net/dpaa2: support for Rx packet parsing and packet type
>> net/dpaa2: link status update
>> net/dpaa2: basic stats support
>> net/dpaa2: enable stashing for LS2088A devices
>> net/dpaa2: handle non-hardware backed buffer pool
>> net/dpaa2: enable physical addressing for packet buffers
>> config: add configuration for toggling physical addressing
>> net/dpaa2: enable DMA Mapping during device scanning
>> net/dpaa2: enable frame queue based dequeuing
>
> Hi Hemant, Shreyansh,
>
> Can you please rebase the patchset on top of latest next-net, I am
> getting some merge conflics.
>
> Also patchset should update release_17_05.rst, instead of release_17_02.rst.
>
Sure, we will do it asap.
> Thanks,
> ferruh
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD
2017-03-17 13:08 ` [dpdk-dev] [PATCH v9 00/22] " Hemant Agrawal
` (22 preceding siblings ...)
2017-03-23 14:34 ` [dpdk-dev] [PATCH v9 00/22] NXP DPAA2 PMD Ferruh Yigit
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (23 more replies)
23 siblings, 24 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patches has been split from DPAA2 PMD v8 series [2] as per
comments received on ML [3].)
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
network SoC PMD. This version of the driver supports NXP LS208xA,
LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
Dependency:
This patchset is to be applied over
a) NXP DPAA2 FSLMC Bus Patches [4] and
b) NXP DPAA2 Mempool patches [5]
Prerequisites:
- For running the PMD, NXP's SoC (board) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
[3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
[4] http://dpdk.org/ml/archives/dev/2017-March/061258.html
[5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
---
v10:
* Rebased on next-net (b36be54c)
* Removing "-Wno-strict-alias" from makefile
v9:
* Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
* Rebased over master (17.02, 630f6ec1)
* remove the eth_driver usages
v8:
* rebased over master (17.02: 35b09d76)
* Removed all drivers/common/* code and moved to drivers/bus/fslmc
* Updated documentation to remove non-open source dependency
* Reduced shared symbols in map files
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (22):
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
net/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
net/dpaa2: add mc dpni object support
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add MTU configuration support
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
net/dpaa2: enable DMA Mapping during device scanning
net/dpaa2: enable frame queue based dequeuing
MAINTAINERS | 3 +
config/common_base | 11 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 11 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
drivers/net/Makefile | 1 +
drivers/net/dpaa2/Makefile | 76 ++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 ++++++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1035 ++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 +++++++++
drivers/net/dpaa2/mc/dpni.c | 739 ++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 ++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 +++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 +++++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 +
21 files changed, 5858 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 02/22] doc: add DPAA2 NIC details Hemant Agrawal
` (22 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 2 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/net/Makefile | 1 +
drivers/net/dpaa2/Makefile | 61 +++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 137 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 ++
9 files changed, 265 insertions(+)
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/MAINTAINERS b/MAINTAINERS
index a1d4756..b70cde8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -350,8 +350,10 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index 198fda5..4d6f459 100644
--- a/config/common_base
+++ b/config/common_base
@@ -302,6 +302,11 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 47a5eee..487ed7e 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -54,3 +54,8 @@ CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
# 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/net/Makefile b/drivers/net/Makefile
index 89001d7..7b8b6a2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
DIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
new file mode 100644
index 0000000..4f5dbf7
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,61 @@
+# 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/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+
+# versioning export map
+EXPORT_MAP := rte_pmd_dpaa2_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+
+LDLIBS += -lrte_bus_fslmc
+
+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..939c56c
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,137 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ 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");
+ rte_eth_dev_release_port(eth_dev);
+ return -ENOMEM;
+ }
+ }
+ eth_dev->device = &dpaa2_dev->device;
+ dpaa2_dev->eth_dev = eth_dev;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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..8591cc0
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.05 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 70c3a5e..48c7a1c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -107,6 +107,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_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
@@ -152,6 +153,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += -L$(ARMV8_CRYPTO_LIB_PATH) -
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += -lrte_pmd_crypto_scheduler
endif # CONFIG_RTE_LIBRTE_CRYPTODEV
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_mempool_dpaa2
+endif # CONFIG_RTE_LIBRTE_DPAA2_PMD
+
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
_LDLIBS-y += --no-whole-archive
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 02/22] doc: add DPAA2 NIC details
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 03/22] net/dpaa2: add debug log support Hemant Agrawal
` (21 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
5 files changed, 636 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index b70cde8..4c2fcac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -354,6 +354,7 @@ M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..7d7a6c5
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,614 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+ For example, the *aarch64* Linaro Toolchain, which can be obtained from
+ `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+
+2. **Linux Kernel**
+
+ It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+ Any *aarch64* supporting filesystem can be used. For example,
+ Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+ from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+As an alternative method, DPAA2 PMD can also be executed using images provided
+as part of SDK from NXP. The SDK includes all the above prerequisites necessary
+to bring up a DPAA2 board.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 5248625..5139ca6 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -39,6 +39,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 3e48224..9578b8a 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -84,6 +84,17 @@ New Features
performance enhancements viz. configurable TX data ring, Receive
Data Ring, ability to register memory regions.
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
Resolved Issues
---------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 03/22] net/dpaa2: add debug log support
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
` (20 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 4f5dbf7..3e3c8d1 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 939c56c..dc3865f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -92,8 +97,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 04/22] config: enable support for DPAA2 debug logging
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (2 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 03/22] net/dpaa2: add debug log support Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
` (19 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 4d6f459..b93ca42 100644
--- a/config/common_base
+++ b/config/common_base
@@ -305,6 +305,11 @@ 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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 487ed7e..a7d305a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -59,3 +59,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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 05/22] net/dpaa2: add mc dpni object support
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (3 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (18 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 3 +
drivers/net/dpaa2/mc/dpni.c | 739 +++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 ++++++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 ++++++++++++++
6 files changed, 2964 insertions(+)
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 3e3c8d1..1b372bd 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -45,8 +45,10 @@ CFLAGS += $(WERROR_FLAGS)
endif
CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -56,6 +58,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/net/dpaa2/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/dpaa2/mc/fsl_dpkg.h b/drivers/net/dpaa2/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 06/22] net/dpaa2: adding eth ops to dpaa2
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (4 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (17 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 426 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 1b372bd..43a9e83 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -49,6 +49,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
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 dc3865f..030919a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 07/22] net/dpaa2: add RSS flow distribution
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (5 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
` (16 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 43a9e83..c2ef774 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -58,6 +58,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
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 030919a..92d334c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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;
priv->hw = dpni_dev;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 08/22] net/dpaa2: configure MAC address at init
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (6 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (15 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 92d334c..6462e0b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -443,6 +444,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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 09/22] net/dpaa2: attach the buffer pool to dpni
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (7 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (14 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/net/dpaa2/Makefile | 4 +++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 57 +++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 62 ++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 6 ++++
4 files changed, 129 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index c2ef774..5b3a020 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -50,6 +50,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
+CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -64,8 +65,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
# library dependencies
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_eal lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += lib/librte_mempool lib/librte_mbuf
DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/bus/fslmc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += drivers/mempool/dpaa2
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_mempool_dpaa2
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 6462e0b..e1bdeef 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -475,6 +488,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 10/22] net/dpaa2: add support for L3 and L4 checksum offload
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (8 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (13 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e1bdeef..5328ed9 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 11/22] net/dpaa2: add support for promiscuous mode
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (9 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
` (12 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 5328ed9..fc46c0b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 12/22] net/dpaa2: add MTU configuration support
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (10 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (11 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index fc46c0b..d1c1d26 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 13/22] net/dpaa2: enable packet Rx and Tx operations
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (11 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (10 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 5b3a020..6f227ae 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -60,6 +60,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d1c1d26..ae2549b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 14/22] net/dpaa2: support for Rx packet parsing and packet type
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (12 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 15/22] net/dpaa2: link status update Hemant Agrawal
` (9 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 ae2549b..9c0efcb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 15/22] net/dpaa2: link status update
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (13 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 16/22] net/dpaa2: basic stats support Hemant Agrawal
` (8 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 9c0efcb..8bf1579 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 16/22] net/dpaa2: basic stats support
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (14 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 15/22] net/dpaa2: link status update Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (7 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 8bf1579..34e435f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 17/22] net/dpaa2: enable stashing for LS2088A devices
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (15 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 16/22] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (6 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 34e435f..8d6f419 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 18/22] net/dpaa2: handle non-hardware backed buffer pool
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (16 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (5 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..a94761c 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_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),
+ rte_dpaa2_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 +380,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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 19/22] net/dpaa2: enable physical addressing for packet buffers
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (17 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
` (4 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 a94761c..49b4558 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 20/22] config: add configuration for toggling physical addressing
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (18 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (3 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index b93ca42..12143ae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -295,6 +295,7 @@ CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX=n
# Compile Support Libraries for NXP DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 a7d305a..6b3f3cc 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile NXP DPAA2 FSL-MC Bus
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 21/22] net/dpaa2: enable DMA Mapping during device scanning
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (19 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
` (2 subsequent siblings)
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 8d6f419..e7b2745 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v10 22/22] net/dpaa2: enable frame queue based dequeuing
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (20 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-03-24 13:35 ` Hemant Agrawal
2017-03-24 14:58 ` [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD Ferruh Yigit
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
23 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-03-24 13:35 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e7b2745..986404b 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (21 preceding siblings ...)
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-03-24 14:58 ` Ferruh Yigit
2017-03-24 15:19 ` Shreyansh Jain
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
23 siblings, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-03-24 14:58 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 3/24/2017 1:35 PM, Hemant Agrawal wrote:
> This patches has been split from DPAA2 PMD v8 series [2] as per
> comments received on ML [3].)
>
> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> network SoC PMD. This version of the driver supports NXP LS208xA,
> LS204xA and LS108x families Network SoCs.
>
> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> designed for high-speed network packet processing. It uses a bus name
> ‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
>
> Dependency:
> This patchset is to be applied over
> a) NXP DPAA2 FSLMC Bus Patches [4] and
> b) NXP DPAA2 Mempool patches [5]
>
> Prerequisites:
> - For running the PMD, NXP's SoC (board) is required.
> Information about obtaining relevant software is available in the docs
> as part of the patch.
>
> References:
> [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
> [2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
> [3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
> [4] http://dpdk.org/ml/archives/dev/2017-March/061258.html
> [5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
>
> ---
> v10:
> * Rebased on next-net (b36be54c)
> * Removing "-Wno-strict-alias" from makefile
>
> v9:
> * Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
> * Rebased over master (17.02, 630f6ec1)
> * remove the eth_driver usages
>
> v8:
> * rebased over master (17.02: 35b09d76)
> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
> * Updated documentation to remove non-open source dependency
> * Reduced shared symbols in map files
>
> v7:
> * rebased over master (17.02)
> * fix the shared lib compilation
> * re partitiion the patches as per Ferruh comments.
> * handling Ferruh's comment for NXP dpaa2 driver
>
> v6:
> * rebased over master (61207d0)
> * removing DPAA2_COMMON as configurable option
> * renaming drivers bus, pool libraries removing 'pmd'
> * Headers of Licenses
> * exposed variable renaming with *rte_* prefix
> * handling Ferruh's comment for NXP dpaa2 driver
> * moving around MAINTAINER and DOC file patches
>
> v5:
> * rebased over master (6818a7f4)
>
> v4:
> * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
>
> v3:
> * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
> * Fixed comment from John on Patch-0003 for documentation
> * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
> another series
>
> v2:
> * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
> * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
> * removed documentation warnings and missing information.
> * removed arm64 part specific code from driver
> * changed rte_panic to errors
> * reduced checkpatch warnings
>
> Hemant Agrawal (22):
> net/dpaa2: introducing NXP DPAA2 PMD driver
> doc: add DPAA2 NIC details
> net/dpaa2: add debug log support
> config: enable support for DPAA2 debug logging
> net/dpaa2: add mc dpni object support
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add RSS flow distribution
> net/dpaa2: configure MAC address at init
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for L3 and L4 checksum offload
> net/dpaa2: add support for promiscuous mode
> net/dpaa2: add MTU configuration support
> net/dpaa2: enable packet Rx and Tx operations
> net/dpaa2: support for Rx packet parsing and packet type
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: handle non-hardware backed buffer pool
> net/dpaa2: enable physical addressing for packet buffers
> config: add configuration for toggling physical addressing
> net/dpaa2: enable DMA Mapping during device scanning
> net/dpaa2: enable frame queue based dequeuing
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD
2017-03-24 14:58 ` [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD Ferruh Yigit
@ 2017-03-24 15:19 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-03-24 15:19 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Hemant Agrawal, dev
> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Friday, March 24, 2017 8:29 PM
> To: Hemant Agrawal <hemant.agrawal@nxp.com>; dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com;
> jerin.jacob@caviumnetworks.com
> Subject: Re: [PATCH v10 00/22] NXP DPAA2 PMD
>
> On 3/24/2017 1:35 PM, Hemant Agrawal wrote:
> > This patches has been split from DPAA2 PMD v8 series [2] as per
> > comments received on ML [3].)
> >
> > The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> > network SoC PMD. This version of the driver supports NXP LS208xA,
> > LS204xA and LS108x families Network SoCs.
> >
> > DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> > designed for high-speed network packet processing. It uses a bus name
> > ‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
> >
> > Dependency:
> > This patchset is to be applied over
> > a) NXP DPAA2 FSLMC Bus Patches [4] and
> > b) NXP DPAA2 Mempool patches [5]
> >
> > Prerequisites:
> > - For running the PMD, NXP's SoC (board) is required.
> > Information about obtaining relevant software is available in the docs
> > as part of the patch.
> >
> > References:
> > [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
> > [2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
> > [3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
> > [4] http://dpdk.org/ml/archives/dev/2017-March/061258.html
> > [5] http://dpdk.org/ml/archives/dev/2017-March/060476.html
> >
> > ---
> > v10:
> > * Rebased on next-net (b36be54c)
> > * Removing "-Wno-strict-alias" from makefile
> >
> > v9:
> > * Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
> > * Rebased over master (17.02, 630f6ec1)
> > * remove the eth_driver usages
> >
> > v8:
> > * rebased over master (17.02: 35b09d76)
> > * Removed all drivers/common/* code and moved to drivers/bus/fslmc
> > * Updated documentation to remove non-open source dependency
> > * Reduced shared symbols in map files
> >
> > v7:
> > * rebased over master (17.02)
> > * fix the shared lib compilation
> > * re partitiion the patches as per Ferruh comments.
> > * handling Ferruh's comment for NXP dpaa2 driver
> >
> > v6:
> > * rebased over master (61207d0)
> > * removing DPAA2_COMMON as configurable option
> > * renaming drivers bus, pool libraries removing 'pmd'
> > * Headers of Licenses
> > * exposed variable renaming with *rte_* prefix
> > * handling Ferruh's comment for NXP dpaa2 driver
> > * moving around MAINTAINER and DOC file patches
> >
> > v5:
> > * rebased over master (6818a7f4)
> >
> > v4:
> > * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus
> Arch.
> >
> > v3:
> > * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus
> Arch.
> > * Fixed comment from John on Patch-0003 for documentation
> > * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed
> through
> > another series
> >
> > v2:
> > * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced
> drivers/bus
> > * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced
> drivers/pool
> > * removed documentation warnings and missing information.
> > * removed arm64 part specific code from driver
> > * changed rte_panic to errors
> > * reduced checkpatch warnings
> >
> > Hemant Agrawal (22):
> > net/dpaa2: introducing NXP DPAA2 PMD driver
> > doc: add DPAA2 NIC details
> > net/dpaa2: add debug log support
> > config: enable support for DPAA2 debug logging
> > net/dpaa2: add mc dpni object support
> > net/dpaa2: adding eth ops to dpaa2
> > net/dpaa2: add RSS flow distribution
> > net/dpaa2: configure MAC address at init
> > net/dpaa2: attach the buffer pool to dpni
> > net/dpaa2: add support for L3 and L4 checksum offload
> > net/dpaa2: add support for promiscuous mode
> > net/dpaa2: add MTU configuration support
> > net/dpaa2: enable packet Rx and Tx operations
> > net/dpaa2: support for Rx packet parsing and packet type
> > net/dpaa2: link status update
> > net/dpaa2: basic stats support
> > net/dpaa2: enable stashing for LS2088A devices
> > net/dpaa2: handle non-hardware backed buffer pool
> > net/dpaa2: enable physical addressing for packet buffers
> > config: add configuration for toggling physical addressing
> > net/dpaa2: enable DMA Mapping during device scanning
> > net/dpaa2: enable frame queue based dequeuing
>
> Series applied to dpdk-next-net/master, thanks.
Thank you Ferruh.
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 00/22] NXP DPAA2 PMD
2017-03-24 13:35 ` [dpdk-dev] [PATCH v10 " Hemant Agrawal
` (22 preceding siblings ...)
2017-03-24 14:58 ` [dpdk-dev] [PATCH v10 00/22] NXP DPAA2 PMD Ferruh Yigit
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (22 more replies)
23 siblings, 23 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patches has been split from DPAA2 PMD v8 series [2] as per
comments received on ML [3].)
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
network SoC PMD. This version of the driver supports NXP LS208xA,
LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
Dependency:
This patchset is to be applied over
a) NXP DPAA2 FSLMC Bus Patches [4] and
b) NXP DPAA2 Mempool patches [5]
Prerequisites:
- For running the PMD, NXP's SoC (board) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
[3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
[4] http://dpdk.org/ml/archives/dev/2017-April/063480.html
[5] http://dpdk.org/ml/archives/dev/2017-April/063503.html
---
v11:
* Rebased on master (17.05-rc1) & patchset [4] & [5]
v10:
* Rebased on next-net (b36be54c)
* Removing "-Wno-strict-alias" from makefile
v9:
* Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
* Rebased over master (17.02, 630f6ec1)
* remove the eth_driver usages
v8:
* rebased over master (17.02: 35b09d76)
* Removed all drivers/common/* code and moved to drivers/bus/fslmc
* Updated documentation to remove non-open source dependency
* Reduced shared symbols in map files
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (22):
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
net/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
net/dpaa2: add mc dpni object support
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add MTU configuration support
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
net/dpaa2: enable DMA Mapping during device scanning
net/dpaa2: enable frame queue based dequeuing
MAINTAINERS | 3 +
config/common_base | 11 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 11 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
drivers/Makefile | 1 +
drivers/bus/Makefile | 4 +
drivers/mempool/Makefile | 4 +
drivers/net/Makefile | 2 +
drivers/net/dpaa2/Makefile | 70 ++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 ++++++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1035 ++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 +++++++++
drivers/net/dpaa2/mc/dpni.c | 739 ++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 ++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 +++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 +++++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 +
24 files changed, 5862 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details Hemant Agrawal
` (21 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 2 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/Makefile | 1 +
drivers/bus/Makefile | 4 +
drivers/mempool/Makefile | 4 +
drivers/net/Makefile | 2 +
drivers/net/dpaa2/Makefile | 57 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 137 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 ++
12 files changed, 271 insertions(+)
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/MAINTAINERS b/MAINTAINERS
index d0a08cb..b783014 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -366,8 +366,10 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index c02e259..0caf585 100644
--- a/config/common_base
+++ b/config/common_base
@@ -311,6 +311,11 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=n
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 47a5eee..487ed7e 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -54,3 +54,8 @@ CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
# 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/Makefile b/drivers/Makefile
index 19459fd..a7d0fc5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -35,6 +35,7 @@ DIRS-y += bus
DIRS-y += mempool
DEPDIRS-mempool := bus
DIRS-y += net
+DEPDIRS-net := bus mempool
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 1aab1cc..d3a3768 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -33,6 +33,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL),y)
CONFIG_RTE_LIBRTE_FSLMC_BUS = $(CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL)
endif
diff --git a/drivers/mempool/Makefile b/drivers/mempool/Makefile
index 8fd40e1..a51ef9a 100644
--- a/drivers/mempool/Makefile
+++ b/drivers/mempool/Makefile
@@ -33,6 +33,10 @@ include $(RTE_SDK)/mk/rte.vars.mk
core-libs := librte_eal librte_mempool librte_ring
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL = $(CONFIG_RTE_LIBRTE_DPAA2_PMD)
+endif
+
DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL) += dpaa2
DEPDIRS-dpaa2 = $(core-libs)
DIRS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += ring
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index bac7057..7a26d65 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -49,6 +49,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DEPDIRS-bonding = $(core-libs) librte_cmdline
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
DEPDIRS-cxgbe = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
+DEPDIRS-dpaa2 = $(core-libs)
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DEPDIRS-e1000 = $(core-libs)
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
new file mode 100644
index 0000000..c91e743
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,57 @@
+# 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/bus/fslmc/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
+
+LDLIBS += -lrte_bus_fslmc
+
+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..939c56c
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,137 @@
+/*-
+ * 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"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ 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");
+ rte_eth_dev_release_port(eth_dev);
+ return -ENOMEM;
+ }
+ }
+ eth_dev->device = &dpaa2_dev->device;
+ dpaa2_dev->eth_dev = eth_dev;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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..8591cc0
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.05 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 4c659e9..8f8189f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -113,6 +113,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_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
@@ -165,6 +166,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += -lrte_pmd_sw_event
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += -lrte_pmd_octeontx_ssovf
endif # CONFIG_RTE_LIBRTE_EVENTDEV
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_mempool_dpaa2
+endif # CONFIG_RTE_LIBRTE_DPAA2_PMD
+
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
_LDLIBS-y += --no-whole-archive
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 12:23 ` Shreyansh Jain
2017-04-10 4:54 ` [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide Shreyansh Jain
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 03/22] net/dpaa2: add debug log support Hemant Agrawal
` (20 subsequent siblings)
22 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 614 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
5 files changed, 636 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index b783014..4b05cfc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -370,6 +370,7 @@ M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..7d7a6c5
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,614 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+ For example, the *aarch64* Linaro Toolchain, which can be obtained from
+ `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+
+2. **Linux Kernel**
+
+ It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+ Any *aarch64* supporting filesystem can be used. For example,
+ Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+ from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+As an alternative method, DPAA2 PMD can also be executed using images provided
+as part of SDK from NXP. The SDK includes all the above prerequisites necessary
+to bring up a DPAA2 board.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 4537113..503fd82 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -40,6 +40,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 4968b8f..4c24550 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -16,6 +16,17 @@ DPDK Release 17.05
xdg-open build/doc/html/guides/rel_notes/release_17_05.html
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
New Features
------------
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-04-09 12:23 ` Shreyansh Jain
2017-04-10 4:54 ` [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide Shreyansh Jain
1 sibling, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-04-09 12:23 UTC (permalink / raw)
To: Hemant Agrawal, ferruh.yigit; +Cc: john.mcnamara, dev
Hello Ferruh,
> -----Original Message-----
> From: Hemant Agrawal [mailto:hemant.agrawal@nxp.com]
> Sent: Sunday, April 09, 2017 1:41 PM
> To: dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com; ferruh.yigit@intel.com;
> jerin.jacob@caviumnetworks.com
> Subject: [PATCH v11 02/22] doc: add DPAA2 NIC details
>
> This patch adds the NXP dpaa2 architecture and pmd details
> in the Network interfaces section.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Acked-by: John McNamara <john.mcnamara@intel.com>
> ---
> MAINTAINERS | 1 +
> doc/guides/nics/dpaa2.rst | 614
> +++++++++++++++++++++++++++++++++
> doc/guides/nics/features/dpaa2.ini | 9 +
> doc/guides/nics/index.rst | 1 +
> doc/guides/rel_notes/release_17_05.rst | 11 +
> 5 files changed, 636 insertions(+)
> create mode 100644 doc/guides/nics/dpaa2.rst
> create mode 100644 doc/guides/nics/features/dpaa2.ini
>
[...]
> +There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
> +compatible board:
> +
> +1. **ARM 64 Tool Chain**
> +
> + For example, the *aarch64* Linaro Toolchain, which can be obtained from
> + `here <https://releases.linaro.org/components/toolchain/binaries/4.9-
> 2017.01/aarch64-linux-gnu>`_.
> +
> +2. **Linux Kernel**
> +
> + It can be obtained from `NXP's Github hosting <https://github.com/qoriq-
> open-source/linux>`_.
> +
> +3. **Rootfile system**
> +
> + Any *aarch64* supporting filesystem can be used. For example,
> + Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
> + from `here <http://cdimage.ubuntu.com/ubuntu-
> base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
> +
There was a patch which I posted over previous series (v10) for removing 'here' and warning it was generating in "make doc". I will push that once again over this.
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details Hemant Agrawal
2017-04-09 12:23 ` Shreyansh Jain
@ 2017-04-10 4:54 ` Shreyansh Jain
2017-04-10 7:46 ` Mcnamara, John
2017-04-11 14:58 ` Ferruh Yigit
1 sibling, 2 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-04-10 4:54 UTC (permalink / raw)
To: ferruh.yigit, Hemant Agrawal; +Cc: dev, john.mcnamara, Shreyansh Jain
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
doc/guides/nics/dpaa2.rst | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
index 7d7a6c5..46225b6 100644
--- a/doc/guides/nics/dpaa2.rst
+++ b/doc/guides/nics/dpaa2.rst
@@ -441,8 +441,7 @@ compatible board:
1. **ARM 64 Tool Chain**
- For example, the *aarch64* Linaro Toolchain, which can be obtained from
- `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+ For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
2. **Linux Kernel**
--
2.7.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide
2017-04-10 4:54 ` [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide Shreyansh Jain
@ 2017-04-10 7:46 ` Mcnamara, John
2017-04-11 14:58 ` Ferruh Yigit
1 sibling, 0 replies; 549+ messages in thread
From: Mcnamara, John @ 2017-04-10 7:46 UTC (permalink / raw)
To: Shreyansh Jain, Yigit, Ferruh, Hemant Agrawal; +Cc: dev
> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
> Sent: Monday, April 10, 2017 5:55 AM
> To: Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Cc: dev@dpdk.org; Mcnamara, John <john.mcnamara@intel.com>; Shreyansh Jain
> <shreyansh.jain@nxp.com>
> Subject: [PATCH] doc: fix build error in DPAA2 PMD guide
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide
2017-04-10 4:54 ` [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide Shreyansh Jain
2017-04-10 7:46 ` Mcnamara, John
@ 2017-04-11 14:58 ` Ferruh Yigit
2017-04-11 17:13 ` Shreyansh Jain
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-04-11 14:58 UTC (permalink / raw)
To: Shreyansh Jain, Hemant Agrawal; +Cc: dev, john.mcnamara
On 4/10/2017 5:54 AM, Shreyansh Jain wrote:
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
> doc/guides/nics/dpaa2.rst | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
> index 7d7a6c5..46225b6 100644
> --- a/doc/guides/nics/dpaa2.rst
> +++ b/doc/guides/nics/dpaa2.rst
> @@ -441,8 +441,7 @@ compatible board:
>
> 1. **ARM 64 Tool Chain**
>
> - For example, the *aarch64* Linaro Toolchain, which can be obtained from
> - `here <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
> + For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
I think this is no more valid with v12 of PMD [1], removing from patchwork.
[1]
http://dpdk.org/dev/patchwork/patch/23484/
>
> 2. **Linux Kernel**
>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide
2017-04-11 14:58 ` Ferruh Yigit
@ 2017-04-11 17:13 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-04-11 17:13 UTC (permalink / raw)
To: Ferruh Yigit, Hemant Agrawal; +Cc: dev, john.mcnamara
Hi Ferruh,
> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Tuesday, April 11, 2017 8:28 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Cc: dev@dpdk.org; john.mcnamara@intel.com
> Subject: Re: [dpdk-dev] [PATCH] doc: fix build error in DPAA2 PMD guide
>
> On 4/10/2017 5:54 AM, Shreyansh Jain wrote:
> > Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> > ---
> > doc/guides/nics/dpaa2.rst | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
> > index 7d7a6c5..46225b6 100644
> > --- a/doc/guides/nics/dpaa2.rst
> > +++ b/doc/guides/nics/dpaa2.rst
> > @@ -441,8 +441,7 @@ compatible board:
> >
> > 1. **ARM 64 Tool Chain**
> >
> > - For example, the *aarch64* Linaro Toolchain, which can be obtained from
> > - `here <https://releases.linaro.org/components/toolchain/binaries/4.9-
> 2017.01/aarch64-linux-gnu>`_.
> > + For example, the `*aarch64* Linaro Toolchain
> <https://releases.linaro.org/components/toolchain/binaries/4.9-
> 2017.01/aarch64-linux-gnu>`_.
>
> I think this is no more valid with v12 of PMD [1], removing from patchwork.
Yes, that is already integrated now.
Thanks for removing from patchwork - it skipped my mind.
>
> [1]
> http://dpdk.org/dev/patchwork/patch/23484/
>
> >
> > 2. **Linux Kernel**
> >
> >
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 03/22] net/dpaa2: add debug log support
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
` (19 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index c91e743..86db137 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 939c56c..dc3865f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,8 @@ static struct rte_dpaa2_driver rte_dpaa2_pmd;
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;
@@ -65,6 +68,8 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
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;
@@ -92,8 +97,8 @@ rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused,
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 04/22] config: enable support for DPAA2 debug logging
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (2 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 03/22] net/dpaa2: add debug log support Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
` (18 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 0caf585..80538ed 100644
--- a/config/common_base
+++ b/config/common_base
@@ -314,6 +314,11 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 487ed7e..a7d305a 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -59,3 +59,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
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 05/22] net/dpaa2: add mc dpni object support
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (3 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (17 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 3 +
drivers/net/dpaa2/mc/dpni.c | 739 +++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 ++++++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 ++++++++++++++
6 files changed, 2964 insertions(+)
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 86db137..889181d 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -45,8 +45,10 @@ CFLAGS += $(WERROR_FLAGS)
endif
CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -56,6 +58,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
LDLIBS += -lrte_bus_fslmc
diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/net/dpaa2/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/dpaa2/mc/fsl_dpkg.h b/drivers/net/dpaa2/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 06/22] net/dpaa2: adding eth ops to dpaa2
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (4 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (16 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 426 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 889181d..4350f45 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -49,6 +49,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
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 dc3865f..030919a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 */
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 07/22] net/dpaa2: add RSS flow distribution
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (5 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
` (15 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 4350f45..7f88e9b 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -58,6 +58,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
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 030919a..92d334c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,8 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
}
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;
@@ -141,6 +142,7 @@ 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;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,18 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
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;
}
@@ -183,7 +197,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
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;
@@ -373,7 +387,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_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;
+ int i, ret, hw_id;
PMD_INIT_FUNC_TRACE();
@@ -415,7 +429,16 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
}
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;
priv->hw = dpni_dev;
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 */
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 08/22] net/dpaa2: configure MAC address at init
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (6 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (14 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 92d334c..6462e0b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,7 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
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;
@@ -443,6 +444,9 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,25 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,11 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev)
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 */
};
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 09/22] net/dpaa2: attach the buffer pool to dpni
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (7 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (13 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/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 ++++
4 files changed, 127 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 7f88e9b..1f66c0b 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -50,6 +50,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
+CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -63,5 +64,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_mempool_dpaa2
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 @@ dpaa2_distset_to_dpkg_profile_cfg(
}
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 6462e0b..e1bdeef 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"
@@ -63,6 +64,8 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
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;
@@ -187,6 +190,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,13 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
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,
+ rte_dpaa2_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. */
@@ -388,7 +399,9 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
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();
@@ -475,6 +488,55 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
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 = rte_dpaa2_pmd.driver.name;
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 */
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 10/22] net/dpaa2: add support for L3 and L4 checksum offload
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (8 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (12 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e1bdeef..5328ed9 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,17 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
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;
@@ -252,8 +262,13 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,
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);
@@ -302,6 +317,7 @@ dpaa2_dev_start(struct rte_eth_dev *dev)
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;
@@ -337,6 +353,48 @@ dpaa2_dev_start(struct rte_eth_dev *dev)
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;
}
@@ -453,7 +511,13 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
*/
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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 11/22] net/dpaa2: add support for promiscuous mode
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (9 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
` (11 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 5328ed9..fc46c0b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,52 @@ dpaa2_dev_close(struct rte_eth_dev *dev)
}
}
+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,
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 12/22] net/dpaa2: add MTU configuration support
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (10 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (10 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index fc46c0b..d1c1d26 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,39 @@ dpaa2_dev_promiscuous_disable(
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,
@@ -484,6 +517,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
.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,
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 13/22] net/dpaa2: enable packet Rx and Tx operations
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (11 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (9 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 1f66c0b..ce65542 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -60,6 +60,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d1c1d26..ae2549b 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,8 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev)
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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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;
+}
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 14/22] net/dpaa2: support for Rx packet parsing and packet type
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (12 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 15/22] net/dpaa2: link status update Hemant Agrawal
` (8 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 ae2549b..9c0efcb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,28 @@ dpaa2_dev_tx_queue_release(void *q __rte_unused)
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)
{
@@ -517,6 +539,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
.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 25574c0..c1ea33a 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 @@ eth_fd_to_mbuf(const struct qbman_fd *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;
+ /* 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);
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 15/22] net/dpaa2: link status update
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (13 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 16/22] net/dpaa2: basic stats support Hemant Agrawal
` (7 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 9c0efcb..8bf1579 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,7 @@ 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;
+ struct rte_eth_link link;
PMD_INIT_FUNC_TRACE();
@@ -439,6 +492,10 @@ dpaa2_dev_stop(struct rte_eth_dev *dev)
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
@@ -531,6 +588,55 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
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,
@@ -538,6 +644,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
.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,
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 16/22] net/dpaa2: basic stats support
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (14 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 15/22] net/dpaa2: link status update Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (6 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 8bf1579..34e435f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,90 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
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,
@@ -645,6 +729,8 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
.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,
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 17/22] net/dpaa2: enable stashing for LS2088A devices
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (15 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 16/22] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (5 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 34e435f..8d6f419 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,17 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
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) {
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 18/22] net/dpaa2: handle non-hardware backed buffer pool
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (16 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (4 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..deec210 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ eth_mbuf_to_fd(struct rte_mbuf *mbuf,
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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_bpid_info[bpid].bp_list->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),
+ rte_dpaa2_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 +380,29 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
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->ops_index != priv->bp_list->dpaa2_ops_index) {
+ 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 +415,6 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
dpaa2_q->tx_pkts += frames_to_send;
nb_pkts -= frames_to_send;
}
+skip_tx:
return num_tx;
}
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 19/22] net/dpaa2: enable physical addressing for packet buffers
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (17 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
` (3 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 @@ dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
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 deec210..c5d49cb 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)),
rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* need to repopulated some of the fields,
@@ -151,10 +151,11 @@ eth_fd_to_mbuf(const struct qbman_fd *fd)
/* 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 @@ eth_mbuf_to_fd(struct rte_mbuf *mbuf,
/*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);
@@ -219,7 +220,7 @@ eth_copy_mbuf_to_fd(struct rte_mbuf *mbuf,
/*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);
@@ -271,7 +272,7 @@ dpaa2_dev_rx(void *queue, struct rte_mbuf **bufs, uint16_t 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);
+ (dma_addr_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
/*Issue a volatile dequeue command. */
while (1) {
@@ -312,7 +313,8 @@ dpaa2_dev_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
}
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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 20/22] config: add configuration for toggling physical addressing
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (18 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (2 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index 80538ed..c177201 100644
--- a/config/common_base
+++ b/config/common_base
@@ -309,6 +309,7 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=n
# Compile Support Libraries for NXP DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile burst-oriented NXP DPAA2 PMD driver
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index a7d305a..6b3f3cc 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile NXP DPAA2 FSL-MC Bus
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 21/22] net/dpaa2: enable DMA Mapping during device scanning
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (19 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 8d6f419..e7b2745 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,8 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->rx_pkt_burst = dpaa2_dev_rx;
eth_dev->tx_pkt_burst = dpaa2_dev_tx;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v11 22/22] net/dpaa2: enable frame queue based dequeuing
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (20 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-04-09 8:11 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-09 8:11 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e7b2745..986404b 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"
@@ -169,9 +170,8 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
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++) {
@@ -195,7 +195,7 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
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;
}
--
2.1.4
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 " Hemant Agrawal
` (21 preceding siblings ...)
2017-04-09 8:11 ` [dpdk-dev] [PATCH v11 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
` (22 more replies)
22 siblings, 23 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patches has been split from DPAA2 PMD v8 series [2] as per
comments received on ML [3].)
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
network SoC PMD. This version of the driver supports NXP LS208xA,
LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
Dependency:
This patchset is to be applied over
a) NXP DPAA2 FSLMC Bus Patches [4] and
b) NXP DPAA2 Mempool patches [5]
Prerequisites:
- For running the PMD, NXP's SoC (board) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
References:
[1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
[3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
[4] http://dpdk.org/ml/archives/dev/2017-April/063683.html
[5] http://dpdk.org/ml/archives/dev/2017-April/063707.html
---
v12:
* Rebased on net-next & patchset [4] & [5]
* removing config dependency.
v11:
* Rebased on master (17.05-rc1) & patchset [4] & [5]
v10:
* Rebased on next-net (b36be54c)
* Removing "-Wno-strict-alias" from makefile
v9:
* Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
* Rebased over master (17.02, 630f6ec1)
* remove the eth_driver usages
v8:
* rebased over master (17.02: 35b09d76)
* Removed all drivers/common/* code and moved to drivers/bus/fslmc
* Updated documentation to remove non-open source dependency
* Reduced shared symbols in map files
v7:
* rebased over master (17.02)
* fix the shared lib compilation
* re partitiion the patches as per Ferruh comments.
* handling Ferruh's comment for NXP dpaa2 driver
v6:
* rebased over master (61207d0)
* removing DPAA2_COMMON as configurable option
* renaming drivers bus, pool libraries removing 'pmd'
* Headers of Licenses
* exposed variable renaming with *rte_* prefix
* handling Ferruh's comment for NXP dpaa2 driver
* moving around MAINTAINER and DOC file patches
v5:
* rebased over master (6818a7f4)
v4:
* rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (22):
net/dpaa2: introducing NXP DPAA2 PMD driver
doc: add DPAA2 NIC details
net/dpaa2: add debug log support
config: enable support for DPAA2 debug logging
net/dpaa2: add mc dpni object support
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add RSS flow distribution
net/dpaa2: configure MAC address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for L3 and L4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add MTU configuration support
net/dpaa2: enable packet Rx and Tx operations
net/dpaa2: support for Rx packet parsing and packet type
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: handle non-hardware backed buffer pool
net/dpaa2: enable physical addressing for packet buffers
config: add configuration for toggling physical addressing
net/dpaa2: enable DMA Mapping during device scanning
net/dpaa2: enable frame queue based dequeuing
MAINTAINERS | 3 +
config/common_base | 11 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 11 +
doc/guides/nics/dpaa2.rst | 613 +++++++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
drivers/Makefile | 1 +
drivers/net/Makefile | 2 +
drivers/net/dpaa2/Makefile | 70 ++
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 ++++++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1035 ++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 422 +++++++++
drivers/net/dpaa2/mc/dpni.c | 739 ++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 ++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 +++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 +++++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 +
22 files changed, 5853 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details Hemant Agrawal
` (21 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
add support for fsl-mc bus based dpaa2 pmd driver.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
MAINTAINERS | 2 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
drivers/Makefile | 1 +
drivers/net/Makefile | 2 +
drivers/net/dpaa2/Makefile | 57 ++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.c | 137 ++++++++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 44 +++++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
mk/rte.app.mk | 6 ++
10 files changed, 263 insertions(+)
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/MAINTAINERS b/MAINTAINERS
index cd57447..61e8fa2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -374,8 +374,10 @@ F: doc/guides/nics/nfp.rst
NXP dpaa2
M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
+F: drivers/net/dpaa2/
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/config/common_base b/config/common_base
index ab0750b..5812b00 100644
--- a/config/common_base
+++ b/config/common_base
@@ -309,6 +309,11 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=n
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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 0c280d8..d2f174e 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -54,3 +54,8 @@ CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
# 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/Makefile b/drivers/Makefile
index 19459fd..a7d0fc5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -35,6 +35,7 @@ DIRS-y += bus
DIRS-y += mempool
DEPDIRS-mempool := bus
DIRS-y += net
+DEPDIRS-net := bus mempool
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fadd13a..35ed813 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -51,6 +51,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bonding
DEPDIRS-bonding = $(core-libs) librte_cmdline
DIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe
DEPDIRS-cxgbe = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
+DEPDIRS-dpaa2 = $(core-libs)
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += e1000
DEPDIRS-e1000 = $(core-libs)
DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
new file mode 100644
index 0000000..c91e743
--- /dev/null
+++ b/drivers/net/dpaa2/Makefile
@@ -0,0 +1,57 @@
+# 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/bus/fslmc/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
+
+LDLIBS += -lrte_bus_fslmc
+
+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..829d1b9
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -0,0 +1,137 @@
+/*-
+ * 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 <rte_fslmc.h>
+
+#include <fslmc_vfio.h>
+#include "dpaa2_ethdev.h"
+
+static struct rte_dpaa2_driver rte_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 = rte_dpaa2_pmd.driver.name;
+
+ return 0;
+}
+
+static int
+dpaa2_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused)
+{
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ return 0;
+}
+
+static int
+rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused,
+ struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ 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");
+ rte_eth_dev_release_port(eth_dev);
+ return -ENOMEM;
+ }
+ }
+ eth_dev->device = &dpaa2_dev->device;
+ dpaa2_dev->eth_dev = eth_dev;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* Invoke PMD device initialization function */
+ diag = dpaa2_dev_init(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+static int
+rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = dpaa2_dev->eth_dev;
+ dpaa2_dev_uninit(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_pmd = {
+ .drv_type = DPAA2_MC_DPNI_DEVID,
+ .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..8591cc0
--- /dev/null
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -0,0 +1,4 @@
+DPDK_17.05 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0e1a79f..3530ab0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -114,6 +114,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += -lrte_pmd_bnxt
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
_LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2
_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
@@ -166,6 +167,11 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += -lrte_pmd_sw_event
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += -lrte_pmd_octeontx_ssovf
endif # CONFIG_RTE_LIBRTE_EVENTDEV
+ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_mempool_dpaa2
+endif # CONFIG_RTE_LIBRTE_DPAA2_PMD
+
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
_LDLIBS-y += --no-whole-archive
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-12 15:28 ` Ferruh Yigit
2017-04-14 12:08 ` Ferruh Yigit
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 03/22] net/dpaa2: add debug log support Hemant Agrawal
` (20 subsequent siblings)
22 siblings, 2 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch adds the NXP dpaa2 architecture and pmd details
in the Network interfaces section.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
MAINTAINERS | 1 +
doc/guides/nics/dpaa2.rst | 613 +++++++++++++++++++++++++++++++++
doc/guides/nics/features/dpaa2.ini | 9 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_05.rst | 11 +
5 files changed, 635 insertions(+)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
diff --git a/MAINTAINERS b/MAINTAINERS
index 61e8fa2..05f2f5f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -378,6 +378,7 @@ M: Shreyansh Jain <shreyansh.jain@nxp.com>
F: drivers/bus/fslmc/
F: drivers/mempool/dpaa2/
F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
QLogic bnx2x
M: Harish Patil <harish.patil@cavium.com>
diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst
new file mode 100644
index 0000000..46225b6
--- /dev/null
+++ b/doc/guides/nics/dpaa2.rst
@@ -0,0 +1,613 @@
+.. BSD LICENSE
+ Copyright (C) NXP. 2016.
+ 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.
+
+DPAA2 Poll Mode Driver
+======================
+
+The DPAA2 NIC PMD (**librte_pmd_dpaa2**) provides poll mode driver
+support for the inbuilt NIC found in the **NXP DPAA2** SoC family.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+NXP DPAA2 (Data Path Acceleration Architecture Gen2)
+----------------------------------------------------
+
+This section provides an overview of the NXP DPAA2 architecture
+and how it is integrated into the DPDK.
+
+Contents summary
+
+- DPAA2 overview
+- Overview of DPAA2 objects
+- DPAA2 driver architecture overview
+
+DPAA2 Overview
+~~~~~~~~~~~~~~
+
+Reference: `FSL MC BUS in Linux Kernel <https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt>`_.
+
+DPAA2 is a hardware architecture designed for high-speed network
+packet processing. DPAA2 consists of sophisticated mechanisms for
+processing Ethernet packets, queue management, buffer management,
+autonomous L2 switching, virtual Ethernet bridging, and accelerator
+(e.g. crypto) sharing.
+
+A DPAA2 hardware component called the Management Complex (or MC) manages the
+DPAA2 hardware resources. The MC provides an object-based abstraction for
+software drivers to use the DPAA2 hardware.
+
+The MC uses DPAA2 hardware resources such as queues, buffer pools, and
+network ports to create functional objects/devices such as network
+interfaces, an L2 switch, or accelerator instances.
+
+The MC provides memory-mapped I/O command interfaces (MC portals)
+which DPAA2 software drivers use to operate on DPAA2 objects:
+
+The diagram below shows an overview of the DPAA2 resource management
+architecture:
+
+.. code-block:: console
+
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+ | | |
+ +-----------------------------|--------+
+ |
+ | (create,discover,connect
+ | config,use,destroy)
+ |
+ DPAA2 |
+ +------------------------| mc portal |-+
+ | | |
+ | +- - - - - - - - - - - - -V- - -+ |
+ | | | |
+ | | Management Complex (MC) | |
+ | | | |
+ | +- - - - - - - - - - - - - - - -+ |
+ | |
+ | Hardware Hardware |
+ | Resources Objects |
+ | --------- ------- |
+ | -queues -DPRC |
+ | -buffer pools -DPMCP |
+ | -Eth MACs/ports -DPIO |
+ | -network interface -DPNI |
+ | profiles -DPMAC |
+ | -queue portals -DPBP |
+ | -MC portals ... |
+ | ... |
+ | |
+ +--------------------------------------+
+
+The MC mediates operations such as create, discover,
+connect, configuration, and destroy. Fast-path operations
+on data, such as packet transmit/receive, are not mediated by
+the MC and are done directly using memory mapped regions in
+DPIO objects.
+
+Overview of DPAA2 Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The section provides a brief overview of some key DPAA2 objects.
+A simple scenario is described illustrating the objects involved
+in creating a network interfaces.
+
+DPRC (Datapath Resource Container)
+
+ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+
+.. code-block:: console
+
+ +---------------------------------------------------------+
+ | DPRC |
+ | |
+ | +-------+ +-------+ +-------+ +-------+ +-------+ |
+ | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | |
+ | +-------+ +-------+ +-------+ +---+---+ +---+---+ |
+ | | DPMCP | | DPIO | |
+ | +-------+ +-------+ |
+ | | DPMCP | |
+ | +-------+ |
+ | |
+ +---------------------------------------------------------+
+
+From the point of view of an OS, a DPRC behaves similar to a plug and
+play bus, like PCI. DPRC commands can be used to enumerate the contents
+of the DPRC, discover the hardware objects present (including mappable
+regions and interrupts).
+
+.. code-block:: console
+
+ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
+ DPMCP.2 DPIO.2
+ DPMCP.3
+
+Hardware objects can be created and destroyed dynamically, providing
+the ability to hot plug/unplug objects in and out of the DPRC.
+
+A DPRC has a mappable MMIO region (an MC portal) that can be used
+to send MC commands. It has an interrupt for status events (like
+hotplug).
+
+All objects in a container share the same hardware "isolation context".
+This means that with respect to an IOMMU the isolation granularity
+is at the DPRC (container) level, not at the individual object
+level.
+
+DPRCs can be defined statically and populated with objects
+via a config file passed to the MC when firmware starts
+it. There is also a Linux user space tool called "restool"
+that can be used to create/destroy containers and objects
+dynamically.
+
+DPAA2 Objects for an Ethernet Network Interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+queuing mechanisms, configuration mechanisms, buffer management,
+physical ports, and interrupts. DPAA2 uses a more granular approach
+utilizing multiple hardware objects. Each object provides specialized
+functions. Groups of these objects are used by software to provide
+Ethernet network interface functionality. This approach provides
+efficient use of finite hardware resources, flexibility, and
+performance advantages.
+
+The diagram below shows the objects needed for a simple
+network interface configuration on a system with 2 CPUs.
+
+.. code-block:: console
+
+ +---+---+ +---+---+
+ CPU0 CPU1
+ +---+---+ +---+---+
+ | |
+ +---+---+ +---+---+
+ DPIO DPIO
+ +---+---+ +---+---+
+ \ /
+ \ /
+ \ /
+ +---+---+
+ DPNI --- DPBP,DPMCP
+ +---+---+
+ |
+ |
+ +---+---+
+ DPMAC
+ +---+---+
+ |
+ port/PHY
+
+Below the objects are described. For each object a brief description
+is provided along with a summary of the kinds of operations the object
+supports and a summary of key resources of the object (MMIO regions
+and IRQs).
+
+DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+hardware device that connects to an Ethernet PHY and allows
+physical transmission and reception of Ethernet frames.
+
+- MMIO regions: none
+- IRQs: DPNI link change
+- commands: set link up/down, link config, get stats, IRQ config, enable, reset
+
+DPNI (Datapath Network Interface): contains TX/RX queues,
+network interface configuration, and RX buffer pool configuration
+mechanisms. The TX/RX queues are in memory and are identified by
+queue number.
+
+- MMIO regions: none
+- IRQs: link state
+- commands: port config, offload config, queue config, parse/classify config, IRQ config, enable, reset
+
+DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+packets and do hardware buffer pool management operations. The DPAA2
+architecture separates the mechanism to access queues (the DPIO object)
+from the queues themselves. The DPIO provides an MMIO interface to
+enqueue/dequeue packets. To enqueue something a descriptor is written
+to the DPIO MMIO region, which includes the target queue number.
+There will typically be one DPIO assigned to each CPU. This allows all
+CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
+expected to be shared by different DPAA2 drivers.
+
+- MMIO regions: queue operations, buffer management
+- IRQs: data availability, congestion notification, buffer pool depletion
+- commands: IRQ config, enable, reset
+
+DPBP (Datapath Buffer Pool): represents a hardware buffer
+pool.
+
+- MMIO regions: none
+- IRQs: none
+- commands: enable, reset
+
+DPMCP (Datapath MC Portal): provides an MC command portal.
+Used by drivers to send commands to the MC to manage
+objects.
+
+- MMIO regions: MC command portal
+- IRQs: command completion
+- commands: IRQ config, enable, reset
+
+Object Connections
+~~~~~~~~~~~~~~~~~~
+
+Some objects have explicit relationships that must
+be configured:
+
+- DPNI <--> DPMAC
+- DPNI <--> DPNI
+- DPNI <--> L2-switch-port
+
+A DPNI must be connected to something such as a DPMAC,
+another DPNI, or L2 switch port. The DPNI connection
+is made via a DPRC command.
+
+.. code-block:: console
+
+ +-------+ +-------+
+ | DPNI | | DPMAC |
+ +---+---+ +---+---+
+ | |
+ +==========+
+
+- DPNI <--> DPBP
+
+A network interface requires a 'buffer pool' (DPBP object) which provides
+a list of pointers to memory where received Ethernet data is to be copied.
+The Ethernet driver configures the DPBPs associated with the network
+interface.
+
+Interrupts
+~~~~~~~~~~
+
+All interrupts generated by DPAA2 objects are message
+interrupts. At the hardware level message interrupts
+generated by devices will normally have 3 components--
+1) a non-spoofable 'device-id' expressed on the hardware
+bus, 2) an address, 3) a data value.
+
+In the case of DPAA2 devices/objects, all objects in the
+same container/DPRC share the same 'device-id'.
+For ARM-based SoC this is the same as the stream ID.
+
+
+DPAA2 DPDK - Poll Mode Driver Overview
+--------------------------------------
+
+This section provides an overview of the drivers for
+DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure"
+drivers and 2) functional object drivers (such as Ethernet).
+
+As described previously, a DPRC is a container that holds the other
+types of DPAA2 objects. It is functionally similar to a plug-and-play
+bus controller.
+
+Each object in the DPRC is a Linux "device" and is bound to a driver.
+The diagram below shows the dpaa2 drivers involved in a networking
+scenario and the objects bound to each driver. A brief description
+of each driver follows.
+
+.. code-block: console
+
+
+ +------------+
+ | DPDK DPAA2 |
+ | PMD |
+ +------------+ +------------+
+ | Ethernet |.......| Mempool |
+ . . . . . . . . . | (DPNI) | | (DPBP) |
+ . +---+---+----+ +-----+------+
+ . ^ | .
+ . | |<enqueue, .
+ . | | dequeue> .
+ . | | .
+ . +---+---V----+ .
+ . . . . . . . . . . .| DPIO driver| .
+ . . | (DPIO) | .
+ . . +-----+------+ .
+ . . | QBMAN | .
+ . . | Driver | .
+ +----+------+-------+ +-----+----- | .
+ | dpaa2 bus | | .
+ | VFIO fslmc-bus |....................|.....................
+ | | |
+ | /bus/fslmc | |
+ +-------------------+ |
+ |
+ ========================== HARDWARE =====|=======================
+ DPIO
+ |
+ DPNI---DPBP
+ |
+ DPMAC
+ |
+ PHY
+ =========================================|========================
+
+
+A brief description of each driver is provided below.
+
+DPAA2 bus driver
+~~~~~~~~~~~~~~~~
+
+The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
+Key functions include:
+
+- Reading the container and setting up vfio group
+- Scanning and parsing the various MC objects and adding them to
+ their respective device list.
+
+Additionally, it also provides the object driver for generic MC objects.
+
+DPIO driver
+~~~~~~~~~~~
+
+The DPIO driver is bound to DPIO objects and provides services that allow
+other drivers such as the Ethernet driver to enqueue and dequeue data for
+their respective objects.
+Key services include:
+
+- Data availability notifications
+- Hardware queuing operations (enqueue and dequeue of data)
+- Hardware buffer pool management
+
+To transmit a packet the Ethernet driver puts data on a queue and
+invokes a DPIO API. For receive, the Ethernet driver registers
+a data availability notification callback. To dequeue a packet
+a DPIO API is used.
+
+There is typically one DPIO object per physical CPU for optimum
+performance, allowing different CPUs to simultaneously enqueue
+and dequeue data.
+
+The DPIO driver operates on behalf of all DPAA2 drivers
+active -- Ethernet, crypto, compression, etc.
+
+DPBP based Mempool driver
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The DPBP driver is bound to a DPBP objects and provides sevices to
+create a hardware offloaded packet buffer mempool.
+
+DPAA2 NIC Driver
+~~~~~~~~~~~~~~~~
+The Ethernet driver is bound to a DPNI and implements the kernel
+interfaces needed to connect the DPAA2 network interface to
+the network stack.
+
+Each DPNI corresponds to a DPDK network interface.
+
+Features
+^^^^^^^^
+
+Features of the DPAA2 PMD are:
+
+- Multiple queues for TX and RX
+- Receive Side Scaling (RSS)
+- Packet type information
+- Checksum offload
+- Promiscuous mode
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2080A/LS2040A
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 PMD on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+ For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu>`_.
+
+2. **Linux Kernel**
+
+ It can be obtained from `NXP's Github hosting <https://github.com/qoriq-open-source/linux>`_.
+
+3. **Rootfile system**
+
+ Any *aarch64* supporting filesystem can be used. For example,
+ Ubuntu 15.10 (Wily) or 16.04 LTS (Xenial) userland which can be obtained
+ from `here <http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz>`_.
+
+As an alternative method, DPAA2 PMD can also be executed using images provided
+as part of SDK from NXP. The SDK includes all the above prerequisites necessary
+to bring up a DPAA2 board.
+
+The following dependencies are not part of DPDK and must be installed
+separately:
+
+- **NXP Linux SDK**
+
+ NXP Linux software development kit (SDK) includes support for family
+ of QorIQ® ARM-Architecture-based system on chip (SoC) processors
+ and corresponding boards.
+
+ It includes the Linux board support packages (BSPs) for NXP SoCs,
+ a fully operational tool chain, kernel and board specific modules.
+
+ SDK and related information can be obtained from: `NXP QorIQ SDK <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.
+
+- **DPDK Helper Scripts**
+
+ DPAA2 based resources can be configured easily with the help of ready scripts
+ as provided in the DPDK helper repository.
+
+ `DPDK Helper Scripts <https://github.com/qoriq-open-source/dpdk-helper>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.0.0** and higher.
+- Supported architectures: **arm64 LE**.
+
+- Follow the DPDK :ref:`Getting Started Guide for Linux <linux_gsg>` to setup the basic DPDK environment.
+
+.. note::
+
+ Some part of fslmc bus code (mc flib - object library) routines are
+ dual licensed (BSD & GPLv2).
+
+Pre-Installation Configuration
+------------------------------
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_FSLMC_BUS`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_bus_fslmc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_PMD`` (default ``n``)
+
+ By default it is enabled only for defconfig_arm64-dpaa2-* config.
+ Toggle compilation of the ``librte_pmd_dpaa2`` driver.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER`` (default ``n``)
+
+ Toggle display of generic debugging messages
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA`` (default ``y``)
+
+ Toggle to use physical address vs virtual address for hardware accelerators.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT`` (default ``n``)
+
+ Toggle display of initialization related messages.
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_RX`` (default ``n``)
+
+ Toggle display of receive fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX`` (default ``n``)
+
+ Toggle display of transmit fast path run-time message
+
+- ``CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE`` (default ``n``)
+
+ Toggle display of transmit fast path buffer free run-time message
+
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 PMD for Linux arm64 gcc target, run the
+following ``make`` command:
+
+.. code-block:: console
+
+ cd <DPDK-source-directory>
+ make config T=arm64-dpaa2-linuxapp-gcc install
+
+.. _dpaa2_testpmd_example:
+
+Running testpmd
+~~~~~~~~~~~~~~~
+
+This section demonstrates how to launch ``testpmd`` with DPAA2 device
+managed by ``librte_pmd_dpaa2`` in the Linux operating system.
+
+#. Configure the resource container:
+
+ Configure resources in MC and create the DPRC container:
+
+ .. code-block:: console
+
+ export the DPRC container
+ e.g. export DPRCT=dprc.2
+
+#. Start ``testpmd`` with basic parameters:
+
+ .. code-block:: console
+
+ ./arm64-dpaa2-linuxapp-gcc/testpmd -c 0xff -n 1 \
+ -- -i --portmask=0x3 --nb-cores=1 --no-flush-rx
+
+ Example output:
+
+ .. code-block:: console
+
+ .....
+ EAL: Registered [pci] bus.
+ EAL: Registered [fslmc] bus.
+ EAL: Detected 8 lcore(s)
+ EAL: Probing VFIO support...
+ EAL: VFIO support initialized
+ .....
+ PMD: DPAA2: Processing Container = dprc.2
+ EAL: fslmc: DPRC contains = 51 devices
+ EAL: fslmc: Bus scan completed
+ .....
+ Configuring Port 0 (socket 0)
+ Port 0: 00:00:00:00:00:01
+ Configuring Port 1 (socket 0)
+ Port 1: 00:00:00:00:00:02
+ .....
+ Checking link statuses...
+ Port 0 Link Up - speed 10000 Mbps - full-duplex
+ Port 1 Link Up - speed 10000 Mbps - full-duplex
+ Done
+ testpmd>
+
+Limitations
+-----------
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
+
+Maximum packet length
+~~~~~~~~~~~~~~~~~~~~~
+
+The DPAA2 SoC family support a maximum of a 10240 jumbo frame. The value
+is fixed and cannot be changed. So, even when the ``rxmode.max_rx_pkt_len``
+member of ``struct rte_eth_conf`` is set to a value lower than 10240, frames
+up to 10240 bytes can still reach the host interface.
diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
new file mode 100644
index 0000000..b176208
--- /dev/null
+++ b/doc/guides/nics/features/dpaa2.ini
@@ -0,0 +1,9 @@
+;
+; Supported features of the 'dpaa2' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux VFIO = Y
+ARMv8 = Y
+Usage doc = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 3305e80..03391d0 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -41,6 +41,7 @@ Network Interface Controller Drivers
bnx2x
bnxt
cxgbe
+ dpaa2
e1000em
ena
enic
diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index bf4afe0..5f9d807 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -16,6 +16,17 @@ DPDK Release 17.05
xdg-open build/doc/html/guides/rel_notes/release_17_05.html
+* **Added a new driver for NXP DPAA2 - FSLMC bus.**
+
+ Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
+
+* **Added a new driver for NXP DPAA2 Network PMD.**
+
+ Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
+ "Network Interface Controller Drivers" document for more details on this new
+ driver.
New Features
------------
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-04-12 15:28 ` Ferruh Yigit
2017-04-13 9:22 ` Shreyansh Jain
2017-04-14 12:08 ` Ferruh Yigit
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-04-12 15:28 UTC (permalink / raw)
To: Hemant Agrawal
Cc: dev, thomas.monjalon, bruce.richardson, shreyansh.jain,
john.mcnamara, jerin.jacob
On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
> This patch adds the NXP dpaa2 architecture and pmd details
> in the Network interfaces section.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Acked-by: John McNamara <john.mcnamara@intel.com>
> ---
> MAINTAINERS | 1 +
> doc/guides/nics/dpaa2.rst | 613 +++++++++++++++++++++++++++++++++
Hi Hemant,
A doc clean-up patch just merged into next-net [1], can you please check
if dpaa2 documentation can benefit from this clean-up, and send a patch
if required?
Thanks,
ferruh
[1]
http://dpdk.org/ml/archives/dev/2017-April/063822.html
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-12 15:28 ` Ferruh Yigit
@ 2017-04-13 9:22 ` Shreyansh Jain
2017-04-13 9:18 ` Ferruh Yigit
0 siblings, 1 reply; 549+ messages in thread
From: Shreyansh Jain @ 2017-04-13 9:22 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev
On Wednesday 12 April 2017 08:58 PM, Ferruh Yigit wrote:
> On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
>> This patch adds the NXP dpaa2 architecture and pmd details
>> in the Network interfaces section.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> Acked-by: John McNamara <john.mcnamara@intel.com>
>> ---
>> MAINTAINERS | 1 +
>> doc/guides/nics/dpaa2.rst | 613 +++++++++++++++++++++++++++++++++
>
> Hi Hemant,
>
> A doc clean-up patch just merged into next-net [1], can you please check
> if dpaa2 documentation can benefit from this clean-up, and send a patch
> if required?
Just to confirm, I will push just the doc change patch over the
net-next - not the complete DPAA2 PMD patch once again. Isn't it?
>
> Thanks,
> ferruh
>
> [1]
> http://dpdk.org/ml/archives/dev/2017-April/063822.html
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-13 9:22 ` Shreyansh Jain
@ 2017-04-13 9:18 ` Ferruh Yigit
0 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-04-13 9:18 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev
On 4/13/2017 10:22 AM, Shreyansh Jain wrote:
> On Wednesday 12 April 2017 08:58 PM, Ferruh Yigit wrote:
>> On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
>>> This patch adds the NXP dpaa2 architecture and pmd details
>>> in the Network interfaces section.
>>>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> Acked-by: John McNamara <john.mcnamara@intel.com>
>>> ---
>>> MAINTAINERS | 1 +
>>> doc/guides/nics/dpaa2.rst | 613 +++++++++++++++++++++++++++++++++
>>
>> Hi Hemant,
>>
>> A doc clean-up patch just merged into next-net [1], can you please check
>> if dpaa2 documentation can benefit from this clean-up, and send a patch
>> if required?
>
> Just to confirm, I will push just the doc change patch over the
> net-next - not the complete DPAA2 PMD patch once again. Isn't it?
Correct, patch should be for next-net, because Shijith's work merged
into next-net.
>
>>
>> Thanks,
>> ferruh
>>
>> [1]
>> http://dpdk.org/ml/archives/dev/2017-April/063822.html
>>
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details Hemant Agrawal
2017-04-12 15:28 ` Ferruh Yigit
@ 2017-04-14 12:08 ` Ferruh Yigit
2017-04-14 16:50 ` Shreyansh Jain
1 sibling, 1 reply; 549+ messages in thread
From: Ferruh Yigit @ 2017-04-14 12:08 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
> This patch adds the NXP dpaa2 architecture and pmd details
> in the Network interfaces section.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Acked-by: John McNamara <john.mcnamara@intel.com>
<...>
> diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
> index bf4afe0..5f9d807 100644
> --- a/doc/guides/rel_notes/release_17_05.rst
> +++ b/doc/guides/rel_notes/release_17_05.rst
> @@ -16,6 +16,17 @@ DPDK Release 17.05
>
> xdg-open build/doc/html/guides/rel_notes/release_17_05.html
>
> +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
> +
> + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on this new
> + driver.
> +
> +* **Added a new driver for NXP DPAA2 Network PMD.**
> +
> + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
> + "Network Interface Controller Drivers" document for more details on this new
> + driver.
These should be below "New Features" section. Can you please send a
patch to fix this?
Thanks,
ferruh
>
> New Features
> ------------
>
^ permalink raw reply [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details
2017-04-14 12:08 ` Ferruh Yigit
@ 2017-04-14 16:50 ` Shreyansh Jain
0 siblings, 0 replies; 549+ messages in thread
From: Shreyansh Jain @ 2017-04-14 16:50 UTC (permalink / raw)
To: Ferruh Yigit
Cc: thomas.monjalon, bruce.richardson, Hemant Agrawal, dev,
john.mcnamara, jerin.jacob
Hello Ferruh,
> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Friday, April 14, 2017 5:39 PM
> To: Hemant Agrawal <hemant.agrawal@nxp.com>; dev@dpdk.org
> Cc: thomas.monjalon@6wind.com; bruce.richardson@intel.com; Shreyansh Jain
> <shreyansh.jain@nxp.com>; john.mcnamara@intel.com;
> jerin.jacob@caviumnetworks.com
> Subject: Re: [PATCH v12 02/22] doc: add DPAA2 NIC details
>
> On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
> > This patch adds the NXP dpaa2 architecture and pmd details
> > in the Network interfaces section.
> >
> > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> > Acked-by: John McNamara <john.mcnamara@intel.com>
>
> <...>
>
> > diff --git a/doc/guides/rel_notes/release_17_05.rst
> b/doc/guides/rel_notes/release_17_05.rst
> > index bf4afe0..5f9d807 100644
> > --- a/doc/guides/rel_notes/release_17_05.rst
> > +++ b/doc/guides/rel_notes/release_17_05.rst
> > @@ -16,6 +16,17 @@ DPDK Release 17.05
> >
> > xdg-open build/doc/html/guides/rel_notes/release_17_05.html
> >
> > +* **Added a new driver for NXP DPAA2 - FSLMC bus.**
> > +
> > + Added the new bus "fslmc" driver for NXP DPAA2 devices. See the
> > + "Network Interface Controller Drivers" document for more details on this
> new
> > + driver.
> > +
> > +* **Added a new driver for NXP DPAA2 Network PMD.**
> > +
> > + Added the new "dpaa2" net driver for NXP DPAA2 devices. See the
> > + "Network Interface Controller Drivers" document for more details on this
> new
> > + driver.
>
> These should be below "New Features" section. Can you please send a
> patch to fix this?
Thanks for highlighting.
Done. In a separate patch targeted on net-next.
>
> Thanks,
> ferruh
>
> >
> > New Features
> > ------------
> >
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 03/22] net/dpaa2: add debug log support
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 01/22] net/dpaa2: introducing NXP DPAA2 PMD driver Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 02/22] doc: add DPAA2 NIC details Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
` (19 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 5 +++++
drivers/net/dpaa2/dpaa2_ethdev.c | 9 +++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index c91e743..86db137 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 829d1b9..0b3dd67 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -45,6 +45,7 @@
#include <rte_ethdev.h>
#include <rte_fslmc.h>
+#include <fslmc_logs.h>
#include <fslmc_vfio.h>
#include "dpaa2_ethdev.h"
@@ -53,6 +54,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;
@@ -65,6 +68,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;
@@ -92,8 +97,8 @@
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");
rte_eth_dev_release_port(eth_dev);
return -ENOMEM;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 04/22] config: enable support for DPAA2 debug logging
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (2 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 03/22] net/dpaa2: add debug log support Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
` (18 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 5 +++++
config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/config/common_base b/config/common_base
index 5812b00..92bd9c9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -312,6 +312,11 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=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
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index d2f174e..6e8f6fd 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -59,3 +59,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
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 05/22] net/dpaa2: add mc dpni object support
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (3 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 04/22] config: enable support for DPAA2 debug logging Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
` (17 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
This patch add support for dpni object support in MC driver.
DPNI represent a network interface object in DPAA2.
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/Makefile | 3 +
drivers/net/dpaa2/mc/dpni.c | 739 +++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpkg.h | 184 ++++++
drivers/net/dpaa2/mc/fsl_dpni.h | 1217 +++++++++++++++++++++++++++++++++++
drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 334 ++++++++++
drivers/net/dpaa2/mc/fsl_net.h | 487 ++++++++++++++
6 files changed, 2964 insertions(+)
create mode 100644 drivers/net/dpaa2/mc/dpni.c
create mode 100644 drivers/net/dpaa2/mc/fsl_dpkg.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni.h
create mode 100644 drivers/net/dpaa2/mc/fsl_dpni_cmd.h
create mode 100644 drivers/net/dpaa2/mc/fsl_net.h
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 86db137..889181d 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -45,8 +45,10 @@ CFLAGS += $(WERROR_FLAGS)
endif
CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
+CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -56,6 +58,7 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
LDLIBS += -lrte_bus_fslmc
diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c
new file mode 100644
index 0000000..3330614
--- /dev/null
+++ b/drivers/net/dpaa2/mc/dpni.c
@@ -0,0 +1,739 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpni.h>
+#include <fsl_dpni_cmd.h>
+
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf)
+{
+ int i, j;
+ int offset = 0;
+ int param = 1;
+ uint64_t *params = (uint64_t *)key_cfg_buf;
+
+ if (!key_cfg_buf || !cfg)
+ return -EINVAL;
+
+ params[0] |= mc_enc(0, 8, cfg->num_extracts);
+ params[0] = cpu_to_le64(params[0]);
+
+ if (cfg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS)
+ return -EINVAL;
+
+ for (i = 0; i < cfg->num_extracts; i++) {
+ switch (cfg->extracts[i].type) {
+ case DPKG_EXTRACT_FROM_HDR:
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.from_hdr.prot);
+ params[param] |= mc_enc(8, 4,
+ cfg->extracts[i].extract.from_hdr.type);
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.from_hdr.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_hdr.offset);
+ params[param] |= mc_enc(32, 32,
+ cfg->extracts[i].extract.
+ from_hdr.field);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ params[param] |= mc_enc(0, 8,
+ cfg->extracts[i].extract.
+ from_hdr.hdr_index);
+ break;
+ case DPKG_EXTRACT_FROM_DATA:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_data.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_data.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ case DPKG_EXTRACT_FROM_PARSE:
+ params[param] |= mc_enc(16, 8,
+ cfg->extracts[i].extract.
+ from_parse.size);
+ params[param] |= mc_enc(24, 8,
+ cfg->extracts[i].extract.
+ from_parse.offset);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params[param] |= mc_enc(
+ 24, 8, cfg->extracts[i].num_of_byte_masks);
+ params[param] |= mc_enc(32, 4, cfg->extracts[i].type);
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ for (offset = 0, j = 0;
+ j < DPKG_NUM_OF_MASKS;
+ offset += 16, j++) {
+ params[param] |= mc_enc(
+ (offset), 8, cfg->extracts[i].masks[j].mask);
+ params[param] |= mc_enc(
+ (offset + 8), 8,
+ cfg->extracts[i].masks[j].offset);
+ }
+ params[param] = cpu_to_le64(params[param]);
+ param++;
+ }
+ return 0;
+}
+
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ cmd_flags,
+ 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
+ cmd_flags,
+ dprc_token);
+ DPNI_CMD_CREATE(cmd, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ CMD_CREATE_RSP_GET_OBJ_ID_PARAM0(cmd, *obj_id);
+
+ return 0;
+}
+
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
+ cmd_flags,
+ dprc_token);
+ /* set object id to destroy */
+ CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, object_id);
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_IS_ENABLED(cmd, *en);
+
+ return 0;
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_OFFLOAD(cmd, type, config);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_OFFLOAD(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_OFFLOAD(cmd, *config);
+
+ return 0;
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QDID(cmd, qtype);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, *max_frame_length);
+
+ return 0;
+}
+
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_UNICAST_PROMISC(cmd, en);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_UNICAST_PROMISC(cmd, *en);
+
+ return 0;
+}
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+ cmd_flags,
+ 0);
+
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_API_VERSION(cmd, *major_ver, *minor_ver);
+
+ return 0;
+}
+
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QUEUE(cmd, queue, qid);
+
+ return 0;
+}
+
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_STATISTICS(cmd, page);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_STATISTICS(cmd, stat);
+
+ return 0;
+}
+
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
+ cmd_flags,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/dpaa2/mc/fsl_dpkg.h b/drivers/net/dpaa2/mc/fsl_dpkg.h
new file mode 100644
index 0000000..3e0f4b0
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpkg.h
@@ -0,0 +1,184 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPKG_H_
+#define __FSL_DPKG_H_
+
+#include <fsl_net.h>
+
+/* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+ */
+
+/** Key Generator properties */
+
+/**
+ * Number of masks per key extraction
+ */
+#define DPKG_NUM_OF_MASKS 4
+/**
+ * Number of extractions per key profile
+ */
+#define DPKG_MAX_NUM_OF_EXTRACTS 10
+
+/**
+ * enum dpkg_extract_from_hdr_type - Selecting extraction by header types
+ * @DPKG_FROM_HDR: Extract selected bytes from header, by offset
+ * @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
+ * @DPKG_FULL_FIELD: Extract a full field
+ */
+enum dpkg_extract_from_hdr_type {
+ DPKG_FROM_HDR = 0,
+ DPKG_FROM_FIELD = 1,
+ DPKG_FULL_FIELD = 2
+};
+
+/**
+ * enum dpkg_extract_type - Enumeration for selecting extraction type
+ * @DPKG_EXTRACT_FROM_HDR: Extract from the header
+ * @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
+ * @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
+ * e.g. can be used to extract header existence;
+ * please refer to 'Parse Result definition' section in the parser BG
+ */
+enum dpkg_extract_type {
+ DPKG_EXTRACT_FROM_HDR = 0,
+ DPKG_EXTRACT_FROM_DATA = 1,
+ DPKG_EXTRACT_FROM_PARSE = 3
+};
+
+/**
+ * struct dpkg_mask - A structure for defining a single extraction mask
+ * @mask: Byte mask for the extracted content
+ * @offset: Offset within the extracted content
+ */
+struct dpkg_mask {
+ uint8_t mask;
+ uint8_t offset;
+};
+
+/**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
+ * DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
+ * DPKG_EXTRACT_FROM_DATA: selects 'from_data';
+ * DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
+ * @extract: Selects extraction method
+ * @num_of_byte_masks: Defines the number of valid entries in the array below;
+ * This is also the number of bytes to be used as masks
+ * @masks: Masks parameters
+ */
+struct dpkg_extract {
+ enum dpkg_extract_type type;
+ /**
+ * union extract - Selects extraction method
+ * @from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @from_data - Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @from_parse - Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ */
+ union {
+ /**
+ * struct from_hdr - Used when 'type = DPKG_EXTRACT_FROM_HDR'
+ * @prot: Any of the supported headers
+ * @type: Defines the type of header extraction:
+ * DPKG_FROM_HDR: use size & offset below;
+ * DPKG_FROM_FIELD: use field, size and offset below;
+ * DPKG_FULL_FIELD: use field below
+ * @field: One of the supported fields (NH_FLD_)
+ *
+ * @size: Size in bytes
+ * @offset: Byte offset
+ * @hdr_index: Clear for cases not listed below;
+ * Used for protocols that may have more than a single
+ * header, 0 indicates an outer header;
+ * Supported protocols (possible values):
+ * NET_PROT_VLAN (0, HDR_INDEX_LAST);
+ * NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
+ * NET_PROT_IP(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv4(0, HDR_INDEX_LAST);
+ * NET_PROT_IPv6(0, HDR_INDEX_LAST);
+ */
+
+ struct {
+ enum net_prot prot;
+ enum dpkg_extract_from_hdr_type type;
+ uint32_t field;
+ uint8_t size;
+ uint8_t offset;
+ uint8_t hdr_index;
+ } from_hdr;
+ /**
+ * struct from_data
+ * Used when 'type = DPKG_EXTRACT_FROM_DATA'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_data;
+
+ /**
+ * struct from_parse
+ * Used when 'type = DPKG_EXTRACT_FROM_PARSE'
+ * @size: Size in bytes
+ * @offset: Byte offset
+ */
+ struct {
+ uint8_t size;
+ uint8_t offset;
+ } from_parse;
+ } extract;
+
+ uint8_t num_of_byte_masks;
+ struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
+};
+
+/**
+ * struct dpkg_profile_cfg - A structure for defining a full Key Generation
+ * profile (rule)
+ * @num_extracts: Defines the number of valid entries in the array below
+ * @extracts: Array of required extractions
+ */
+struct dpkg_profile_cfg {
+ uint8_t num_extracts;
+ struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
+};
+
+#endif /* __FSL_DPKG_H_ */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h
new file mode 100644
index 0000000..ef14f85
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni.h
@@ -0,0 +1,1217 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_DPNI_H
+#define __FSL_DPNI_H
+
+#include <fsl_dpkg.h>
+
+struct fsl_mc_io;
+
+/**
+ * Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+/** General DPNI macros */
+
+/**
+ * Maximum number of traffic classes
+ */
+#define DPNI_MAX_TC 8
+/**
+ * Maximum number of buffer pools per DPNI
+ */
+#define DPNI_MAX_DPBP 8
+/**
+ * Maximum number of storage-profiles per DPNI
+ */
+#define DPNI_MAX_SP 2
+
+/**
+ * All traffic classes considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/**
+ * All flows within traffic class considered; see dpni_set_queue()
+ */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/**
+ * Generate new flow ID; see dpni_set_queue()
+ */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+/**
+ * Tx traffic is always released to a buffer pool on transmit, there are no
+ * resources allocated to have the frames confirmed back to the source after
+ * transmission.
+ */
+#define DPNI_OPT_TX_FRM_RELEASE 0x000001
+/**
+ * Disables support for MAC address filtering for addresses other than primary
+ * MAC address. This affects both unicast and multicast. Promiscuous mode can
+ * still be enabled/disabled for both unicast and multicast. If promiscuous mode
+ * is disabled, only traffic matching the primary MAC address will be accepted.
+ */
+#define DPNI_OPT_NO_MAC_FILTER 0x000002
+/**
+ * Allocate policers for this DPNI. They can be used to rate-limit traffic per
+ * traffic class (TC) basis.
+ */
+#define DPNI_OPT_HAS_POLICING 0x000004
+/**
+ * Congestion can be managed in several ways, allowing the buffer pool to
+ * deplete on ingress, taildrop on each queue or use congestion groups for sets
+ * of queues. If set, it configures a single congestion groups across all TCs.
+ * If reset, a congestion group is allocated for each TC. Only relevant if the
+ * DPNI has multiple traffic classes.
+ */
+#define DPNI_OPT_SHARED_CONGESTION 0x000008
+/**
+ * Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
+ * look-ups are exact match. Note that TCAM is not available on LS1088 and its
+ * variants. Setting this bit on these SoCs will trigger an error.
+ */
+#define DPNI_OPT_HAS_KEY_MASKING 0x000010
+/**
+ * Disables the flow steering table.
+ */
+#define DPNI_OPT_NO_FS 0x000020
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ int dpni_id,
+ uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_cfg - Structure representing DPNI configuration
+ * @mac_addr: Primary MAC address
+ * @adv: Advanced parameters; default is all zeros;
+ * use this structure to change default settings
+ */
+struct dpni_cfg {
+ /**
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @fs_entries: Number of entries in the flow steering table.
+ * This table is used to select the ingress queue for
+ * ingress traffic, targeting a GPP core or another.
+ * In addition it can be used to discard traffic that
+ * matches the set rule. It is either an exact match table
+ * or a TCAM table, depending on DPNI_OPT_ HAS_KEY_MASKING
+ * bit in OPTIONS field. This field is ignored if
+ * DPNI_OPT_NO_FS bit is set in OPTIONS field. Otherwise,
+ * value 0 defaults to 64. Maximum supported value is 1024.
+ * Note that the total number of entries is limited on the
+ * SoC to as low as 512 entries if TCAM is used.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table. This is an exact match table used to filter
+ * ingress traffic based on VLAN IDs. Value 0 disables VLAN
+ * filtering. Maximum supported value is 16.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table. This is an exact match table and allows both
+ * unicast and multicast entries. The primary MAC address
+ * of the network interface is not part of this table,
+ * this contains only entries in addition to it. This
+ * field is ignored if DPNI_OPT_ NO_MAC_FILTER is set in
+ * OPTIONS field. Otherwise, value 0 defaults to 80.
+ * Maximum supported value is 80.
+ * @num_queues: Number of Tx and Rx queues used for traffic
+ * distribution. This is orthogonal to QoS and is only
+ * used to distribute traffic to multiple GPP cores.
+ * This configuration affects the number of Tx queues
+ * (logical FQs, all associated with a single CEETM queue),
+ * Rx queues and Tx confirmation queues, if applicable.
+ * Value 0 defaults to one queue. Maximum supported value
+ * is 8.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * TCs can have different priority levels for the purpose
+ * of Tx scheduling (see DPNI_SET_TX_SELECTION), different
+ * BPs (DPNI_ SET_POOLS), policers. There are dedicated QM
+ * queues for traffic classes (including class queues on
+ * Tx). Value 0 defaults to one TC. Maximum supported value
+ * is 8.
+ * @qos_entries: Number of entries in the QoS classification table. This
+ * table is used to select the TC for ingress traffic. It
+ * is either an exact match or a TCAM table, depending on
+ * DPNI_OPT_ HAS_KEY_MASKING bit in OPTIONS field. This
+ * field is ignored if the DPNI has a single TC. Otherwise,
+ * a value of 0 defaults to 64. Maximum supported value
+ * is 64.
+ */
+ uint32_t options;
+ uint16_t fs_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t mac_filter_entries;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t qos_entries;
+};
+
+/**
+ * dpni_create() - Create the DPNI object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @cfg: Configuration structure
+ * @obj_id: returned object id
+ *
+ * Create the DPNI object, allocate required resources and
+ * perform required initialization.
+ *
+ * The object can be created either by declaring it in the
+ * DPL file, or by calling this function.
+ *
+ * The function accepts an authentication token of a parent
+ * container that this object should be assigned to. The token
+ * can be '0' so the object will be assigned to the default container.
+ * The newly created object can be opened with the returned
+ * object id and using the container's associated tokens and MC portals.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_create(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ const struct dpni_cfg *cfg,
+ uint32_t *obj_id);
+
+/**
+ * dpni_destroy() - Destroy the DPNI object and release all its resources.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dprc_token: Parent container token; '0' for default container
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @object_id: The object id; it must be a valid id within the container that
+ * created this object;
+ *
+ * The function accepts the authentication token of the parent container that
+ * created the object (not the one that currently owns the object). The object
+ * is searched within parent using the provided 'object_id'.
+ * All tokens to the object must be closed before calling destroy.
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_destroy(struct fsl_mc_io *mc_io,
+ uint16_t dprc_token,
+ uint32_t cmd_flags,
+ uint32_t object_id);
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ * @backup_pool: Backup pool
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ int backup_pool;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * dpni_is_enabled() - Check if the DPNI is enabled.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_is_enabled(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @options: Any combination of the following options:
+ * DPNI_OPT_TX_FRM_RELEASE
+ * DPNI_OPT_NO_MAC_FILTER
+ * DPNI_OPT_HAS_POLICING
+ * DPNI_OPT_SHARED_CONGESTION
+ * DPNI_OPT_HAS_KEY_MASKING
+ * DPNI_OPT_NO_FS
+ * @num_queues: Number of Tx and Rx queues used for traffic distribution.
+ * @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
+ * @mac_filter_entries: Number of entries in the MAC address filtering
+ * table.
+ * @vlan_filter_entries: Number of entries in the VLAN address filtering
+ * table.
+ * @qos_entries: Number of entries in the QoS classification table.
+ * @fs_entries: Number of entries in the flow steering table.
+ * @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
+ * than this when adding QoS entries will result
+ * in an error.
+ * @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
+ * key larger than this when composing the hash + FS key
+ * will result in an error.
+ * @wriop_version: Version of WRIOP HW block.
+ * The 3 version values are stored on 6, 5, 5 bits
+ * respectively.
+ * Values returned:
+ * - 0x400 - WRIOP version 1.0.0, used on LS2080 and
+ * variants,
+ * - 0x421 - WRIOP version 1.1.1, used on LS2088 and
+ * variants,
+ * - 0x422 - WRIOP version 1.1.2, used on LS1088 and
+ * variants.
+ */
+struct dpni_attr {
+ uint32_t options;
+ uint8_t num_queues;
+ uint8_t num_tcs;
+ uint8_t mac_filter_entries;
+ uint8_t vlan_filter_entries;
+ uint8_t qos_entries;
+ uint16_t fs_entries;
+ uint8_t qos_key_size;
+ uint8_t fs_key_size;
+ uint16_t wriop_version;
+};
+
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @attr: Object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/**
+ * DPNI errors
+ */
+
+/**
+ * Extract out of frame header error
+ */
+#define DPNI_ERROR_EOFHE 0x00020000
+/**
+ * Frame length error
+ */
+#define DPNI_ERROR_FLE 0x00002000
+/**
+ * Frame physical error
+ */
+#define DPNI_ERROR_FPE 0x00001000
+/**
+ * Parsing header error
+ */
+#define DPNI_ERROR_PHE 0x00000020
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L3CE 0x00000004
+/**
+ * Parser L3 checksum error
+ */
+#define DPNI_ERROR_L4CE 0x00000001
+
+/**
+ * enum dpni_error_action - Defines DPNI behavior for errors
+ * @DPNI_ERROR_ACTION_DISCARD: Discard the frame
+ * @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
+ * @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
+ */
+enum dpni_error_action {
+ DPNI_ERROR_ACTION_DISCARD = 0,
+ DPNI_ERROR_ACTION_CONTINUE = 1,
+ DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
+};
+
+/**
+ * struct dpni_error_cfg - Structure representing DPNI errors treatment
+ * @errors: Errors mask; use 'DPNI_ERROR__<X>
+ * @error_action: The desired action for the errors mask
+ * @set_frame_annotation: Set to '1' to mark the errors in frame annotation
+ * status (FAS); relevant only for the non-discard action
+ */
+struct dpni_error_cfg {
+ uint32_t errors;
+ enum dpni_error_action error_action;
+ int set_frame_annotation;
+};
+
+/**
+ * dpni_set_errors_behavior() - Set errors behavior
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @cfg: Errors configuration
+ *
+ * this function may be called numerous times with different
+ * error masks
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg);
+
+/**
+ * DPNI buffer layout modification options
+ */
+
+/**
+ * Select to modify the time-stamp setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/**
+ * Select to modify the parser-result setting; not applicable for Tx
+ */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/**
+ * Select to modify the frame-status setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/**
+ * Select to modify the private-data-size setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/**
+ * Select to modify the data-alignment setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/**
+ * Select to modify the data-head-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/**
+ * Select to modify the data-tail-room setting
+ */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * enum dpni_queue_type - Identifies a type of queue targeted by the command
+ * @DPNI_QUEUE_RX: Rx queue
+ * @DPNI_QUEUE_TX: Tx queue
+ * @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
+ * @DPNI_QUEUE_RX_ERR: Rx error queue
+ */enum dpni_queue_type {
+ DPNI_QUEUE_RX,
+ DPNI_QUEUE_TX,
+ DPNI_QUEUE_TX_CONFIRM,
+ DPNI_QUEUE_RX_ERR,
+};
+
+/**
+ * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get the layout from
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_set_buffer_layout() - Set buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to set layout on
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * enum dpni_offload - Identifies a type of offload targeted by the command
+ * @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
+ * @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
+ * @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
+ * @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
+ */
+enum dpni_offload {
+ DPNI_OFF_RX_L3_CSUM,
+ DPNI_OFF_RX_L4_CSUM,
+ DPNI_OFF_TX_L3_CSUM,
+ DPNI_OFF_TX_L4_CSUM,
+};
+
+/**
+ * dpni_set_offload() - Set DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, non-zero value enables
+ * the offload.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t config);
+
+/**
+ * dpni_get_offload() - Get DPNI offload configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @type: Type of DPNI offload
+ * @config: Offload configuration.
+ * For checksum offloads, a value of 1 indicates that the
+ * offload is enabled.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_get_offload(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_offload type,
+ uint32_t *config);
+
+/**
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue to get QDID for. For applications lookig to
+ * transmit traffic this should be set to DPNI_QUEUE_TX
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint16_t *qdid);
+
+#define DPNI_STATISTICS_CNT 7
+
+union dpni_statistics {
+ /**
+ * struct page_0 - Page_0 statistics structure
+ * @ingress_all_frames: Ingress frame count
+ * @ingress_all_bytes: Ingress byte count
+ * @ingress_multicast_frames: Ingress multicast frame count
+ * @ingress_multicast_bytes: Ingress multicast byte count
+ * @ingress_broadcast_frames: Ingress broadcast frame count
+ * @ingress_broadcast_bytes: Ingress broadcast byte count
+ */
+ struct {
+ uint64_t ingress_all_frames;
+ uint64_t ingress_all_bytes;
+ uint64_t ingress_multicast_frames;
+ uint64_t ingress_multicast_bytes;
+ uint64_t ingress_broadcast_frames;
+ uint64_t ingress_broadcast_bytes;
+ } page_0;
+ /**
+ * struct page_1 - Page_1 statistics structure
+ * @egress_all_frames: Egress frame count
+ * @egress_all_bytes: Egress byte count
+ * @egress_multicast_frames: Egress multicast frame count
+ * @egress_multicast_bytes: Egress multicast byte count
+ * @egress_broadcast_frames: Egress broadcast frame count
+ * @egress_broadcast_bytes: Egress broadcast byte count
+ */
+ struct {
+ uint64_t egress_all_frames;
+ uint64_t egress_all_bytes;
+ uint64_t egress_multicast_frames;
+ uint64_t egress_multicast_bytes;
+ uint64_t egress_broadcast_frames;
+ uint64_t egress_broadcast_bytes;
+ } page_1;
+ /**
+ * struct page_2 - Page_2 statistics structure
+ * @ingress_filtered_frames: Ingress filtered frame count
+ * @ingress_discarded_frames: Ingress discarded frame count
+ * @ingress_nobuffer_discards: Ingress discarded frame count due to
+ * lack of buffers
+ * @egress_discarded_frames: Egress discarded frame count
+ * @egress_confirmed_frames: Egress confirmed frame count
+ */
+ struct {
+ uint64_t ingress_filtered_frames;
+ uint64_t ingress_discarded_frames;
+ uint64_t ingress_nobuffer_discards;
+ uint64_t egress_discarded_frames;
+ uint64_t egress_confirmed_frames;
+ } page_2;
+ /**
+ * struct raw - raw statistics structure, used to index counters
+ */
+ struct {
+ uint64_t counter[DPNI_STATISTICS_CNT];
+ } raw;
+};
+
+/**
+ * Enable auto-negotiation
+ */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/**
+ * Enable half-duplex mode
+ */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/**
+ * Enable pause frames
+ */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/**
+ * Enable a-symmetric pause frames
+ */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint32_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_max_frame_length() - Set the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t max_frame_length);
+
+/**
+ * dpni_get_max_frame_length() - Get the maximum received frame length.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @max_frame_length: Maximum received frame length (in
+ * bytes); frame is discarded if its
+ * length exceeds this value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t *max_frame_length);
+
+
+/**
+ * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Set to '1' to enable; '0' to disable
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int en);
+
+/**
+ * dpni_get_unicast_promisc() - Get unicast promiscuous mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @en: Returns '1' if enabled; '0' otherwise
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ int *en);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+
+/**
+ * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
+ * port the DPNI is attached to
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address of the physical port, if any, otherwise 0
+ *
+ * The primary MAC address is not modified by this operation.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dist_mode - DPNI distribution mode
+ * @DPNI_DIST_MODE_NONE: No distribution
+ * @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
+ * the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
+ * @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
+ * the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
+ */
+enum dpni_dist_mode {
+ DPNI_DIST_MODE_NONE = 0,
+ DPNI_DIST_MODE_HASH = 1,
+ DPNI_DIST_MODE_FS = 2
+};
+
+/**
+ * enum dpni_fs_miss_action - DPNI Flow Steering miss action
+ * @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
+ * @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
+ * @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
+ */
+enum dpni_fs_miss_action {
+ DPNI_FS_MISS_DROP = 0,
+ DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
+ DPNI_FS_MISS_HASH = 2
+};
+
+/**
+ * struct dpni_fs_tbl_cfg - Flow Steering table configuration
+ * @miss_action: Miss action selection
+ * @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
+ */
+struct dpni_fs_tbl_cfg {
+ enum dpni_fs_miss_action miss_action;
+ uint16_t default_flow_id;
+};
+
+/**
+ * dpni_prepare_key_cfg() - function prepare extract parameters
+ * @cfg: defining a full Key Generation profile (rule)
+ * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
+ *
+ * This function has to be called before the following functions:
+ * - dpni_set_rx_tc_dist()
+ * - dpni_set_qos_table()
+ */
+int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
+ uint8_t *key_cfg_buf);
+
+/**
+ * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
+ * @dist_size: Set the distribution size;
+ * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
+ * 112,128,192,224,256,384,448,512,768,896,1024
+ * @dist_mode: Distribution mode
+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
+ * the extractions to be used for the distribution key by calling
+ * dpni_prepare_key_cfg() relevant only when
+ * 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
+ * @fs_cfg: Flow Steering table configuration; only relevant if
+ * 'dist_mode = DPNI_DIST_MODE_FS'
+ */
+struct dpni_rx_tc_dist_cfg {
+ uint16_t dist_size;
+ enum dpni_dist_mode dist_mode;
+ uint64_t key_cfg_iova;
+ struct dpni_fs_tbl_cfg fs_cfg;
+};
+
+/**
+ * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @cfg: Traffic class distribution configuration
+ *
+ * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
+ * first to prepare the key_cfg_iova parameter
+ *
+ * Return: '0' on Success; error code otherwise.
+ */
+int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t tc_id,
+ const struct dpni_rx_tc_dist_cfg *cfg);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+
+/**
+ * struct dpni_queue - Queue structure
+ * @user_context: User data, presented to the user along with any frames
+ * from this queue. Not relevant for Tx queues.
+ */
+struct dpni_queue {
+ /**
+ * struct destination - Destination structure
+ * @id: ID of the destination, only relevant if DEST_TYPE is > 0.
+ * Identifies either a DPIO or a DPCON object.
+ * Not relevant for Tx queues.
+ * @type: May be one of the following:
+ * 0 - No destination, queue can be manually
+ * queried, but will not push traffic or
+ * notifications to a DPIO;
+ * 1 - The destination is a DPIO. When traffic
+ * becomes available in the queue a FQDAN
+ * (FQ data available notification) will be
+ * generated to selected DPIO;
+ * 2 - The destination is a DPCON. The queue is
+ * associated with a DPCON object for the
+ * purpose of scheduling between multiple
+ * queues. The DPCON may be independently
+ * configured to generate notifications.
+ * Not relevant for Tx queues.
+ * @hold_active: Hold active, maintains a queue scheduled for longer
+ * in a DPIO during dequeue to reduce spread of traffic.
+ * Only relevant if queues are
+ * not affined to a single DPIO.
+ */
+ struct {
+ uint16_t id;
+ enum dpni_dest type;
+ char hold_active;
+ uint8_t priority;
+ } destination;
+ uint64_t user_context;
+ /**
+ * struct flc - FD FLow Context structure
+ * @value: FLC value to set
+ * @stash_control: Boolean, indicates whether the 6 lowest
+ * significant bits are used for stash control.
+ */
+ struct {
+ uint64_t value;
+ char stash_control;
+ } flc;
+};
+
+/**
+ * struct dpni_queue_id - Queue identification, used for enqueue commands
+ * or queue control
+ * @fqid: FQID used for enqueueing to and/or configuration of this
+ * specific FQ
+ * @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI.
+ * Only relevant for Tx queues.
+ */
+struct dpni_queue_id {
+ uint32_t fqid;
+ uint16_t qdbin;
+};
+
+/**
+ * enum dpni_confirmation_mode - Defines DPNI options supported for Tx
+ * confirmation
+ * @DPNI_CONF_AFFINE: For each Tx queue set associated with a sender there is
+ * an affine Tx Confirmation queue
+ * @DPNI_CONF_SINGLE: All Tx queues are associated with a single Tx
+ * confirmation queue
+ * @DPNI_CONF_DISABLE: Tx frames are not confirmed. This must be associated
+ * with proper FD set-up to have buffers release to a Buffer Pool, otherwise
+ * buffers will be leaked
+ */
+enum dpni_confirmation_mode {
+ DPNI_CONF_AFFINE,
+ DPNI_CONF_SINGLE,
+ DPNI_CONF_DISABLE,
+};
+
+/**
+ * dpni_set_tx_confirmation_mode() - Tx confirmation mode
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @mode: Tx confirmation mode
+ *
+ * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
+ * selected at DPNI creation.
+ * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
+ * transmit confirmation (including the private confirmation queues), regardless
+ * of previous settings; Note that in this case, Tx error frames are still
+ * enqueued to the general transmit errors queue.
+ * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
+ * Tx confirmations to a shared Tx conf queue. The ID of the queue when
+ * calling dpni_set/get_queue is -1.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_confirmation_mode mode);
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of data path network interface API
+ * @minor_ver: Minor version of data path network interface API
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t *major_ver,
+ uint16_t *minor_ver);
+
+/**
+ * Set User Context
+ */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+
+/**
+ * Set queue destination configuration
+ */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * Set FD[FLC] configuration for traffic on this queue. Note that FLC values
+ * set with dpni_add_fs_entry, if any, take precedence over values per queue.
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
+/**
+ * Set the queue to hold active mode. This prevents the queue from being
+ * rescheduled between DPIOs while it carries traffic and is active on one
+ * DPNI. Can help reduce reordering when servicing one queue on multiple
+ * CPUs, but the queue is also less likely to push data to multiple CPUs
+ * especially when congested.
+ */
+#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
+
+/**
+ * dpni_set_queue() - Set queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported, although
+ * the command is ignored for Tx
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set
+ * allocated for the same TC.Value must be in
+ * range 0 to NUM_QUEUES - 1
+ * @options: A combination of DPNI_QUEUE_OPT_ values that control
+ * what configuration options are set on the queue
+ * @queue: Queue configuration structure
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ uint8_t options,
+ const struct dpni_queue *queue);
+
+/**
+ * dpni_get_queue() - Get queue parameters
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @qtype: Type of queue - all queue types are supported
+ * @tc: Traffic class, in range 0 to NUM_TCS - 1
+ * @index: Selects the specific queue out of the set allocated
+ * for the same TC. Value must be in range 0 to
+ * NUM_QUEUES - 1
+ * @queue: Queue configuration structure
+ * @qid: Queue identification
+ *
+ * This function returns current queue configuration which can be changed by
+ * calling dpni_set_queue, and queue identification information.
+ * Returned qid.fqid and/or qid.qdbin values can be used to:
+ * - enqueue traffic for Tx queues,
+ * - perform volatile dequeue for Rx and, if applicable, Tx confirmation
+ * clean-up,
+ * - retrieve queue state.
+ *
+ * All these operations are supported through the DPIO run-time API.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_queue(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ enum dpni_queue_type qtype,
+ uint8_t tc,
+ uint8_t index,
+ struct dpni_queue *queue,
+ struct dpni_queue_id *qid);
+
+/**
+ * dpni_get_statistics() - Get DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @page: Selects the statistics page to retrieve, see
+ * DPNI_GET_STATISTICS output.
+ * Pages are numbered 0 to 2.
+ * @stat: Structure containing the statistics
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint8_t page,
+ union dpni_statistics *stat);
+
+/**
+ * dpni_reset_statistics() - Clears DPNI statistics
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset_statistics(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token);
+
+#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
new file mode 100644
index 0000000..bb92ea8
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h
@@ -0,0 +1,334 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 _FSL_DPNI_CMD_H
+#define _FSL_DPNI_CMD_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 7
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN ((0x801 << 4) | (0x1))
+#define DPNI_CMDID_CLOSE ((0x800 << 4) | (0x1))
+#define DPNI_CMDID_CREATE ((0x901 << 4) | (0x1))
+#define DPNI_CMDID_DESTROY ((0x981 << 4) | (0x1))
+#define DPNI_CMDID_GET_API_VERSION ((0xa01 << 4) | (0x1))
+
+#define DPNI_CMDID_ENABLE ((0x002 << 4) | (0x1))
+#define DPNI_CMDID_DISABLE ((0x003 << 4) | (0x1))
+#define DPNI_CMDID_GET_ATTR ((0x004 << 4) | (0x1))
+#define DPNI_CMDID_RESET ((0x005 << 4) | (0x1))
+#define DPNI_CMDID_IS_ENABLED ((0x006 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_POOLS ((0x200 << 4) | (0x1))
+#define DPNI_CMDID_SET_ERRORS_BEHAVIOR ((0x20B << 4) | (0x1))
+
+#define DPNI_CMDID_GET_QDID ((0x210 << 4) | (0x1))
+#define DPNI_CMDID_GET_LINK_STATE ((0x215 << 4) | (0x1))
+#define DPNI_CMDID_SET_MAX_FRAME_LENGTH ((0x216 << 4) | (0x1))
+#define DPNI_CMDID_GET_MAX_FRAME_LENGTH ((0x217 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_UNICAST_PROMISC ((0x222 << 4) | (0x1))
+#define DPNI_CMDID_GET_UNICAST_PROMISC ((0x223 << 4) | (0x1))
+#define DPNI_CMDID_SET_PRIM_MAC ((0x224 << 4) | (0x1))
+#define DPNI_CMDID_GET_PRIM_MAC ((0x225 << 4) | (0x1))
+
+#define DPNI_CMDID_SET_RX_TC_DIST ((0x235 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_STATISTICS ((0x25D << 4) | (0x1))
+#define DPNI_CMDID_RESET_STATISTICS ((0x25E << 4) | (0x1))
+#define DPNI_CMDID_GET_QUEUE ((0x25F << 4) | (0x1))
+#define DPNI_CMDID_SET_QUEUE ((0x260 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_PORT_MAC_ADDR ((0x263 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_BUFFER_LAYOUT ((0x264 << 4) | (0x1))
+#define DPNI_CMDID_SET_BUFFER_LAYOUT ((0x265 << 4) | (0x1))
+
+#define DPNI_CMDID_GET_OFFLOAD ((0x26B << 4) | (0x1))
+#define DPNI_CMDID_SET_OFFLOAD ((0x26C << 4) | (0x1))
+#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE ((0x266 << 4) | (0x1))
+#define DPNI_CMDID_GET_TX_CONFIRMATION_MODE ((0x26D << 4) | (0x1))
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CREATE(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, (cfg)->options); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, (cfg)->num_queues); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, (cfg)->num_tcs); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, (cfg)->mac_filter_entries); \
+ MC_CMD_OP(cmd, 1, 0, 8, uint8_t, (cfg)->vlan_filter_entries); \
+ MC_CMD_OP(cmd, 1, 16, 8, uint8_t, (cfg)->qos_entries); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (cfg)->fs_entries); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
+ MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
+ MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
+ MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
+ MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
+ MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
+ MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
+ MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_IS_ENABLED(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* DPNI_CMD_GET_ATTR is not used, no input parameters */
+
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, (attr)->options); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, (attr)->num_queues); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, (attr)->num_tcs); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, (attr)->mac_filter_entries); \
+ MC_RSP_OP(cmd, 1, 0, 8, uint8_t, (attr)->vlan_filter_entries); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, (attr)->qos_entries); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (attr)->fs_entries); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, (attr)->qos_key_size); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, (attr)->fs_key_size); \
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, (attr)->wriop_version); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, cfg->errors); \
+ MC_CMD_OP(cmd, 0, 32, 4, enum dpni_error_action, cfg->error_action); \
+ MC_CMD_OP(cmd, 0, 36, 1, int, cfg->set_frame_annotation); \
+} while (0)
+
+#define DPNI_CMD_GET_BUFFER_LAYOUT(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+#define DPNI_RSP_GET_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_RSP_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_RSP_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_RSP_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_BUFFER_LAYOUT(cmd, qtype, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 32, 16, uint16_t, (layout)->options); \
+ MC_CMD_OP(cmd, 0, 48, 1, char, (layout)->pass_timestamp); \
+ MC_CMD_OP(cmd, 0, 49, 1, char, (layout)->pass_parser_result); \
+ MC_CMD_OP(cmd, 0, 50, 1, char, (layout)->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 0, 16, uint16_t, (layout)->private_data_size); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, (layout)->data_align); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, (layout)->data_head_room); \
+ MC_CMD_OP(cmd, 1, 48, 16, uint16_t, (layout)->data_tail_room); \
+} while (0)
+
+#define DPNI_CMD_SET_OFFLOAD(cmd, type, config) \
+do { \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, config); \
+} while (0)
+
+#define DPNI_CMD_GET_OFFLOAD(cmd, type) \
+ MC_CMD_OP(cmd, 0, 24, 8, enum dpni_offload, type)
+
+#define DPNI_RSP_GET_OFFLOAD(cmd, config) \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, config)
+
+#define DPNI_CMD_GET_QDID(cmd, qtype) \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_STATISTICS(cmd, page) \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, page)
+
+#define DPNI_RSP_GET_STATISTICS(cmd, stat) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
+ MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
+ MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_MAX_FRAME_LENGTH(cmd, max_frame_length) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, max_frame_length)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_UNICAST_PROMISC(cmd, en) \
+ MC_CMD_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_UNICAST_PROMISC(cmd, en) \
+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->dist_size); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 24, 4, enum dpni_dist_mode, cfg->dist_mode); \
+ MC_CMD_OP(cmd, 0, 28, 4, enum dpni_fs_miss_action, \
+ cfg->fs_cfg.miss_action); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->fs_cfg.default_flow_id); \
+ MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_cfg_iova); \
+} while (0)
+
+#define DPNI_CMD_GET_QUEUE(cmd, qtype, tc, index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+} while (0)
+
+#define DPNI_RSP_GET_QUEUE(cmd, queue, queue_id) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_RSP_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_RSP_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_RSP_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_RSP_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+ MC_RSP_OP(cmd, 4, 0, 32, uint32_t, (queue_id)->fqid); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, (queue_id)->qdbin); \
+} while (0)
+
+#define DPNI_CMD_SET_QUEUE(cmd, qtype, tc, index, options, queue) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, enum dpni_queue_type, qtype); \
+ MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc); \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, index); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, options); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, (queue)->destination.id); \
+ MC_CMD_OP(cmd, 1, 48, 8, uint8_t, (queue)->destination.priority); \
+ MC_CMD_OP(cmd, 1, 56, 4, enum dpni_dest, (queue)->destination.type); \
+ MC_CMD_OP(cmd, 1, 62, 1, char, (queue)->flc.stash_control); \
+ MC_CMD_OP(cmd, 1, 63, 1, char, (queue)->destination.hold_active); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, (queue)->flc.value); \
+ MC_CMD_OP(cmd, 3, 0, 64, uint64_t, (queue)->user_context); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_API_VERSION(cmd, major, minor) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, major);\
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, minor);\
+} while (0)
+
+
+#define DPNI_CMD_SET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_CMD_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#define DPNI_RSP_GET_TX_CONFIRMATION_MODE(cmd, mode) \
+ MC_RSP_OP(cmd, 0, 32, 8, enum dpni_confirmation_mode, mode)
+
+#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/dpaa2/mc/fsl_net.h b/drivers/net/dpaa2/mc/fsl_net.h
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/drivers/net/dpaa2/mc/fsl_net.h
@@ -0,0 +1,487 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * BSD LICENSE
+ *
+ * Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * 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 HOLDERS 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 __FSL_NET_H
+#define __FSL_NET_H
+
+#define LAST_HDR_INDEX 0xFFFFFFFF
+
+/*****************************************************************************/
+/* Protocol fields */
+/*****************************************************************************/
+
+/************************* Ethernet fields *********************************/
+#define NH_FLD_ETH_DA (1)
+#define NH_FLD_ETH_SA (NH_FLD_ETH_DA << 1)
+#define NH_FLD_ETH_LENGTH (NH_FLD_ETH_DA << 2)
+#define NH_FLD_ETH_TYPE (NH_FLD_ETH_DA << 3)
+#define NH_FLD_ETH_FINAL_CKSUM (NH_FLD_ETH_DA << 4)
+#define NH_FLD_ETH_PADDING (NH_FLD_ETH_DA << 5)
+#define NH_FLD_ETH_ALL_FIELDS ((NH_FLD_ETH_DA << 6) - 1)
+
+#define NH_FLD_ETH_ADDR_SIZE 6
+
+/*************************** VLAN fields ***********************************/
+#define NH_FLD_VLAN_VPRI (1)
+#define NH_FLD_VLAN_CFI (NH_FLD_VLAN_VPRI << 1)
+#define NH_FLD_VLAN_VID (NH_FLD_VLAN_VPRI << 2)
+#define NH_FLD_VLAN_LENGTH (NH_FLD_VLAN_VPRI << 3)
+#define NH_FLD_VLAN_TYPE (NH_FLD_VLAN_VPRI << 4)
+#define NH_FLD_VLAN_ALL_FIELDS ((NH_FLD_VLAN_VPRI << 5) - 1)
+
+#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
+ NH_FLD_VLAN_CFI | \
+ NH_FLD_VLAN_VID)
+
+/************************ IP (generic) fields ******************************/
+#define NH_FLD_IP_VER (1)
+#define NH_FLD_IP_DSCP (NH_FLD_IP_VER << 2)
+#define NH_FLD_IP_ECN (NH_FLD_IP_VER << 3)
+#define NH_FLD_IP_PROTO (NH_FLD_IP_VER << 4)
+#define NH_FLD_IP_SRC (NH_FLD_IP_VER << 5)
+#define NH_FLD_IP_DST (NH_FLD_IP_VER << 6)
+#define NH_FLD_IP_TOS_TC (NH_FLD_IP_VER << 7)
+#define NH_FLD_IP_ID (NH_FLD_IP_VER << 8)
+#define NH_FLD_IP_ALL_FIELDS ((NH_FLD_IP_VER << 9) - 1)
+
+#define NH_FLD_IP_PROTO_SIZE 1
+
+/***************************** IPV4 fields *********************************/
+#define NH_FLD_IPV4_VER (1)
+#define NH_FLD_IPV4_HDR_LEN (NH_FLD_IPV4_VER << 1)
+#define NH_FLD_IPV4_TOS (NH_FLD_IPV4_VER << 2)
+#define NH_FLD_IPV4_TOTAL_LEN (NH_FLD_IPV4_VER << 3)
+#define NH_FLD_IPV4_ID (NH_FLD_IPV4_VER << 4)
+#define NH_FLD_IPV4_FLAG_D (NH_FLD_IPV4_VER << 5)
+#define NH_FLD_IPV4_FLAG_M (NH_FLD_IPV4_VER << 6)
+#define NH_FLD_IPV4_OFFSET (NH_FLD_IPV4_VER << 7)
+#define NH_FLD_IPV4_TTL (NH_FLD_IPV4_VER << 8)
+#define NH_FLD_IPV4_PROTO (NH_FLD_IPV4_VER << 9)
+#define NH_FLD_IPV4_CKSUM (NH_FLD_IPV4_VER << 10)
+#define NH_FLD_IPV4_SRC_IP (NH_FLD_IPV4_VER << 11)
+#define NH_FLD_IPV4_DST_IP (NH_FLD_IPV4_VER << 12)
+#define NH_FLD_IPV4_OPTS (NH_FLD_IPV4_VER << 13)
+#define NH_FLD_IPV4_OPTS_COUNT (NH_FLD_IPV4_VER << 14)
+#define NH_FLD_IPV4_ALL_FIELDS ((NH_FLD_IPV4_VER << 15) - 1)
+
+#define NH_FLD_IPV4_ADDR_SIZE 4
+#define NH_FLD_IPV4_PROTO_SIZE 1
+
+/***************************** IPV6 fields *********************************/
+#define NH_FLD_IPV6_VER (1)
+#define NH_FLD_IPV6_TC (NH_FLD_IPV6_VER << 1)
+#define NH_FLD_IPV6_SRC_IP (NH_FLD_IPV6_VER << 2)
+#define NH_FLD_IPV6_DST_IP (NH_FLD_IPV6_VER << 3)
+#define NH_FLD_IPV6_NEXT_HDR (NH_FLD_IPV6_VER << 4)
+#define NH_FLD_IPV6_FL (NH_FLD_IPV6_VER << 5)
+#define NH_FLD_IPV6_HOP_LIMIT (NH_FLD_IPV6_VER << 6)
+#define NH_FLD_IPV6_ID (NH_FLD_IPV6_VER << 7)
+#define NH_FLD_IPV6_ALL_FIELDS ((NH_FLD_IPV6_VER << 8) - 1)
+
+#define NH_FLD_IPV6_ADDR_SIZE 16
+#define NH_FLD_IPV6_NEXT_HDR_SIZE 1
+
+/***************************** ICMP fields *********************************/
+#define NH_FLD_ICMP_TYPE (1)
+#define NH_FLD_ICMP_CODE (NH_FLD_ICMP_TYPE << 1)
+#define NH_FLD_ICMP_CKSUM (NH_FLD_ICMP_TYPE << 2)
+#define NH_FLD_ICMP_ID (NH_FLD_ICMP_TYPE << 3)
+#define NH_FLD_ICMP_SQ_NUM (NH_FLD_ICMP_TYPE << 4)
+#define NH_FLD_ICMP_ALL_FIELDS ((NH_FLD_ICMP_TYPE << 5) - 1)
+
+#define NH_FLD_ICMP_CODE_SIZE 1
+#define NH_FLD_ICMP_TYPE_SIZE 1
+
+/***************************** IGMP fields *********************************/
+#define NH_FLD_IGMP_VERSION (1)
+#define NH_FLD_IGMP_TYPE (NH_FLD_IGMP_VERSION << 1)
+#define NH_FLD_IGMP_CKSUM (NH_FLD_IGMP_VERSION << 2)
+#define NH_FLD_IGMP_DATA (NH_FLD_IGMP_VERSION << 3)
+#define NH_FLD_IGMP_ALL_FIELDS ((NH_FLD_IGMP_VERSION << 4) - 1)
+
+/***************************** TCP fields **********************************/
+#define NH_FLD_TCP_PORT_SRC (1)
+#define NH_FLD_TCP_PORT_DST (NH_FLD_TCP_PORT_SRC << 1)
+#define NH_FLD_TCP_SEQ (NH_FLD_TCP_PORT_SRC << 2)
+#define NH_FLD_TCP_ACK (NH_FLD_TCP_PORT_SRC << 3)
+#define NH_FLD_TCP_OFFSET (NH_FLD_TCP_PORT_SRC << 4)
+#define NH_FLD_TCP_FLAGS (NH_FLD_TCP_PORT_SRC << 5)
+#define NH_FLD_TCP_WINDOW (NH_FLD_TCP_PORT_SRC << 6)
+#define NH_FLD_TCP_CKSUM (NH_FLD_TCP_PORT_SRC << 7)
+#define NH_FLD_TCP_URGPTR (NH_FLD_TCP_PORT_SRC << 8)
+#define NH_FLD_TCP_OPTS (NH_FLD_TCP_PORT_SRC << 9)
+#define NH_FLD_TCP_OPTS_COUNT (NH_FLD_TCP_PORT_SRC << 10)
+#define NH_FLD_TCP_ALL_FIELDS ((NH_FLD_TCP_PORT_SRC << 11) - 1)
+
+#define NH_FLD_TCP_PORT_SIZE 2
+
+/***************************** UDP fields **********************************/
+#define NH_FLD_UDP_PORT_SRC (1)
+#define NH_FLD_UDP_PORT_DST (NH_FLD_UDP_PORT_SRC << 1)
+#define NH_FLD_UDP_LEN (NH_FLD_UDP_PORT_SRC << 2)
+#define NH_FLD_UDP_CKSUM (NH_FLD_UDP_PORT_SRC << 3)
+#define NH_FLD_UDP_ALL_FIELDS ((NH_FLD_UDP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_UDP_PORT_SIZE 2
+
+/*************************** UDP-lite fields *******************************/
+#define NH_FLD_UDP_LITE_PORT_SRC (1)
+#define NH_FLD_UDP_LITE_PORT_DST (NH_FLD_UDP_LITE_PORT_SRC << 1)
+#define NH_FLD_UDP_LITE_ALL_FIELDS \
+ ((NH_FLD_UDP_LITE_PORT_SRC << 2) - 1)
+
+#define NH_FLD_UDP_LITE_PORT_SIZE 2
+
+/*************************** UDP-encap-ESP fields **************************/
+#define NH_FLD_UDP_ENC_ESP_PORT_SRC (1)
+#define NH_FLD_UDP_ENC_ESP_PORT_DST (NH_FLD_UDP_ENC_ESP_PORT_SRC << 1)
+#define NH_FLD_UDP_ENC_ESP_LEN (NH_FLD_UDP_ENC_ESP_PORT_SRC << 2)
+#define NH_FLD_UDP_ENC_ESP_CKSUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 3)
+#define NH_FLD_UDP_ENC_ESP_SPI (NH_FLD_UDP_ENC_ESP_PORT_SRC << 4)
+#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM (NH_FLD_UDP_ENC_ESP_PORT_SRC << 5)
+#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS \
+ ((NH_FLD_UDP_ENC_ESP_PORT_SRC << 6) - 1)
+
+#define NH_FLD_UDP_ENC_ESP_PORT_SIZE 2
+#define NH_FLD_UDP_ENC_ESP_SPI_SIZE 4
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_PORT_SRC (1)
+#define NH_FLD_SCTP_PORT_DST (NH_FLD_SCTP_PORT_SRC << 1)
+#define NH_FLD_SCTP_VER_TAG (NH_FLD_SCTP_PORT_SRC << 2)
+#define NH_FLD_SCTP_CKSUM (NH_FLD_SCTP_PORT_SRC << 3)
+#define NH_FLD_SCTP_ALL_FIELDS ((NH_FLD_SCTP_PORT_SRC << 4) - 1)
+
+#define NH_FLD_SCTP_PORT_SIZE 2
+
+/***************************** DCCP fields *********************************/
+#define NH_FLD_DCCP_PORT_SRC (1)
+#define NH_FLD_DCCP_PORT_DST (NH_FLD_DCCP_PORT_SRC << 1)
+#define NH_FLD_DCCP_ALL_FIELDS ((NH_FLD_DCCP_PORT_SRC << 2) - 1)
+
+#define NH_FLD_DCCP_PORT_SIZE 2
+
+/***************************** IPHC fields *********************************/
+#define NH_FLD_IPHC_CID (1)
+#define NH_FLD_IPHC_CID_TYPE (NH_FLD_IPHC_CID << 1)
+#define NH_FLD_IPHC_HCINDEX (NH_FLD_IPHC_CID << 2)
+#define NH_FLD_IPHC_GEN (NH_FLD_IPHC_CID << 3)
+#define NH_FLD_IPHC_D_BIT (NH_FLD_IPHC_CID << 4)
+#define NH_FLD_IPHC_ALL_FIELDS ((NH_FLD_IPHC_CID << 5) - 1)
+
+/***************************** SCTP fields *********************************/
+#define NH_FLD_SCTP_CHUNK_DATA_TYPE (1)
+#define NH_FLD_SCTP_CHUNK_DATA_FLAGS (NH_FLD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NH_FLD_SCTP_CHUNK_DATA_LENGTH (NH_FLD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NH_FLD_SCTP_CHUNK_DATA_TSN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN (NH_FLD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID (NH_FLD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED (NH_FLD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NH_FLD_SCTP_CHUNK_DATA_BEGINNING (NH_FLD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NH_FLD_SCTP_CHUNK_DATA_END (NH_FLD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS \
+ ((NH_FLD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+/*************************** L2TPV2 fields *********************************/
+#define NH_FLD_L2TPV2_TYPE_BIT (1)
+#define NH_FLD_L2TPV2_LENGTH_BIT (NH_FLD_L2TPV2_TYPE_BIT << 1)
+#define NH_FLD_L2TPV2_SEQUENCE_BIT (NH_FLD_L2TPV2_TYPE_BIT << 2)
+#define NH_FLD_L2TPV2_OFFSET_BIT (NH_FLD_L2TPV2_TYPE_BIT << 3)
+#define NH_FLD_L2TPV2_PRIORITY_BIT (NH_FLD_L2TPV2_TYPE_BIT << 4)
+#define NH_FLD_L2TPV2_VERSION (NH_FLD_L2TPV2_TYPE_BIT << 5)
+#define NH_FLD_L2TPV2_LEN (NH_FLD_L2TPV2_TYPE_BIT << 6)
+#define NH_FLD_L2TPV2_TUNNEL_ID (NH_FLD_L2TPV2_TYPE_BIT << 7)
+#define NH_FLD_L2TPV2_SESSION_ID (NH_FLD_L2TPV2_TYPE_BIT << 8)
+#define NH_FLD_L2TPV2_NS (NH_FLD_L2TPV2_TYPE_BIT << 9)
+#define NH_FLD_L2TPV2_NR (NH_FLD_L2TPV2_TYPE_BIT << 10)
+#define NH_FLD_L2TPV2_OFFSET_SIZE (NH_FLD_L2TPV2_TYPE_BIT << 11)
+#define NH_FLD_L2TPV2_FIRST_BYTE (NH_FLD_L2TPV2_TYPE_BIT << 12)
+#define NH_FLD_L2TPV2_ALL_FIELDS \
+ ((NH_FLD_L2TPV2_TYPE_BIT << 13) - 1)
+
+/*************************** L2TPV3 fields *********************************/
+#define NH_FLD_L2TPV3_CTRL_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_CTRL_VERSION (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_CTRL_LENGTH (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 4)
+#define NH_FLD_L2TPV3_CTRL_CONTROL (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 5)
+#define NH_FLD_L2TPV3_CTRL_SENT (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 6)
+#define NH_FLD_L2TPV3_CTRL_RECV (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 7)
+#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE (NH_FLD_L2TPV3_CTRL_TYPE_BIT << 8)
+#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NH_FLD_L2TPV3_SESS_TYPE_BIT (1)
+#define NH_FLD_L2TPV3_SESS_VERSION (NH_FLD_L2TPV3_SESS_TYPE_BIT << 1)
+#define NH_FLD_L2TPV3_SESS_ID (NH_FLD_L2TPV3_SESS_TYPE_BIT << 2)
+#define NH_FLD_L2TPV3_SESS_COOKIE (NH_FLD_L2TPV3_SESS_TYPE_BIT << 3)
+#define NH_FLD_L2TPV3_SESS_ALL_FIELDS \
+ ((NH_FLD_L2TPV3_SESS_TYPE_BIT << 4) - 1)
+
+/**************************** PPP fields ***********************************/
+#define NH_FLD_PPP_PID (1)
+#define NH_FLD_PPP_COMPRESSED (NH_FLD_PPP_PID << 1)
+#define NH_FLD_PPP_ALL_FIELDS ((NH_FLD_PPP_PID << 2) - 1)
+
+/************************** PPPoE fields ***********************************/
+#define NH_FLD_PPPOE_VER (1)
+#define NH_FLD_PPPOE_TYPE (NH_FLD_PPPOE_VER << 1)
+#define NH_FLD_PPPOE_CODE (NH_FLD_PPPOE_VER << 2)
+#define NH_FLD_PPPOE_SID (NH_FLD_PPPOE_VER << 3)
+#define NH_FLD_PPPOE_LEN (NH_FLD_PPPOE_VER << 4)
+#define NH_FLD_PPPOE_SESSION (NH_FLD_PPPOE_VER << 5)
+#define NH_FLD_PPPOE_PID (NH_FLD_PPPOE_VER << 6)
+#define NH_FLD_PPPOE_ALL_FIELDS ((NH_FLD_PPPOE_VER << 7) - 1)
+
+/************************* PPP-Mux fields **********************************/
+#define NH_FLD_PPPMUX_PID (1)
+#define NH_FLD_PPPMUX_CKSUM (NH_FLD_PPPMUX_PID << 1)
+#define NH_FLD_PPPMUX_COMPRESSED (NH_FLD_PPPMUX_PID << 2)
+#define NH_FLD_PPPMUX_ALL_FIELDS ((NH_FLD_PPPMUX_PID << 3) - 1)
+
+/*********************** PPP-Mux sub-frame fields **************************/
+#define NH_FLD_PPPMUX_SUBFRM_PFF (1)
+#define NH_FLD_PPPMUX_SUBFRM_LXT (NH_FLD_PPPMUX_SUBFRM_PFF << 1)
+#define NH_FLD_PPPMUX_SUBFRM_LEN (NH_FLD_PPPMUX_SUBFRM_PFF << 2)
+#define NH_FLD_PPPMUX_SUBFRM_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 3)
+#define NH_FLD_PPPMUX_SUBFRM_USE_PID (NH_FLD_PPPMUX_SUBFRM_PFF << 4)
+#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS \
+ ((NH_FLD_PPPMUX_SUBFRM_PFF << 5) - 1)
+
+/*************************** LLC fields ************************************/
+#define NH_FLD_LLC_DSAP (1)
+#define NH_FLD_LLC_SSAP (NH_FLD_LLC_DSAP << 1)
+#define NH_FLD_LLC_CTRL (NH_FLD_LLC_DSAP << 2)
+#define NH_FLD_LLC_ALL_FIELDS ((NH_FLD_LLC_DSAP << 3) - 1)
+
+/*************************** NLPID fields **********************************/
+#define NH_FLD_NLPID_NLPID (1)
+#define NH_FLD_NLPID_ALL_FIELDS ((NH_FLD_NLPID_NLPID << 1) - 1)
+
+/*************************** SNAP fields ***********************************/
+#define NH_FLD_SNAP_OUI (1)
+#define NH_FLD_SNAP_PID (NH_FLD_SNAP_OUI << 1)
+#define NH_FLD_SNAP_ALL_FIELDS ((NH_FLD_SNAP_OUI << 2) - 1)
+
+/*************************** LLC SNAP fields *******************************/
+#define NH_FLD_LLC_SNAP_TYPE (1)
+#define NH_FLD_LLC_SNAP_ALL_FIELDS ((NH_FLD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NH_FLD_ARP_HTYPE (1)
+#define NH_FLD_ARP_PTYPE (NH_FLD_ARP_HTYPE << 1)
+#define NH_FLD_ARP_HLEN (NH_FLD_ARP_HTYPE << 2)
+#define NH_FLD_ARP_PLEN (NH_FLD_ARP_HTYPE << 3)
+#define NH_FLD_ARP_OPER (NH_FLD_ARP_HTYPE << 4)
+#define NH_FLD_ARP_SHA (NH_FLD_ARP_HTYPE << 5)
+#define NH_FLD_ARP_SPA (NH_FLD_ARP_HTYPE << 6)
+#define NH_FLD_ARP_THA (NH_FLD_ARP_HTYPE << 7)
+#define NH_FLD_ARP_TPA (NH_FLD_ARP_HTYPE << 8)
+#define NH_FLD_ARP_ALL_FIELDS ((NH_FLD_ARP_HTYPE << 9) - 1)
+
+/*************************** RFC2684 fields ********************************/
+#define NH_FLD_RFC2684_LLC (1)
+#define NH_FLD_RFC2684_NLPID (NH_FLD_RFC2684_LLC << 1)
+#define NH_FLD_RFC2684_OUI (NH_FLD_RFC2684_LLC << 2)
+#define NH_FLD_RFC2684_PID (NH_FLD_RFC2684_LLC << 3)
+#define NH_FLD_RFC2684_VPN_OUI (NH_FLD_RFC2684_LLC << 4)
+#define NH_FLD_RFC2684_VPN_IDX (NH_FLD_RFC2684_LLC << 5)
+#define NH_FLD_RFC2684_ALL_FIELDS ((NH_FLD_RFC2684_LLC << 6) - 1)
+
+/*************************** User defined fields ***************************/
+#define NH_FLD_USER_DEFINED_SRCPORT (1)
+#define NH_FLD_USER_DEFINED_PCDID (NH_FLD_USER_DEFINED_SRCPORT << 1)
+#define NH_FLD_USER_DEFINED_ALL_FIELDS \
+ ((NH_FLD_USER_DEFINED_SRCPORT << 2) - 1)
+
+/*************************** Payload fields ********************************/
+#define NH_FLD_PAYLOAD_BUFFER (1)
+#define NH_FLD_PAYLOAD_SIZE (NH_FLD_PAYLOAD_BUFFER << 1)
+#define NH_FLD_MAX_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 2)
+#define NH_FLD_MIN_FRM_SIZE (NH_FLD_PAYLOAD_BUFFER << 3)
+#define NH_FLD_PAYLOAD_TYPE (NH_FLD_PAYLOAD_BUFFER << 4)
+#define NH_FLD_FRAME_SIZE (NH_FLD_PAYLOAD_BUFFER << 5)
+#define NH_FLD_PAYLOAD_ALL_FIELDS ((NH_FLD_PAYLOAD_BUFFER << 6) - 1)
+
+/*************************** GRE fields ************************************/
+#define NH_FLD_GRE_TYPE (1)
+#define NH_FLD_GRE_ALL_FIELDS ((NH_FLD_GRE_TYPE << 1) - 1)
+
+/*************************** MINENCAP fields *******************************/
+#define NH_FLD_MINENCAP_SRC_IP (1)
+#define NH_FLD_MINENCAP_DST_IP (NH_FLD_MINENCAP_SRC_IP << 1)
+#define NH_FLD_MINENCAP_TYPE (NH_FLD_MINENCAP_SRC_IP << 2)
+#define NH_FLD_MINENCAP_ALL_FIELDS \
+ ((NH_FLD_MINENCAP_SRC_IP << 3) - 1)
+
+/*************************** IPSEC AH fields *******************************/
+#define NH_FLD_IPSEC_AH_SPI (1)
+#define NH_FLD_IPSEC_AH_NH (NH_FLD_IPSEC_AH_SPI << 1)
+#define NH_FLD_IPSEC_AH_ALL_FIELDS ((NH_FLD_IPSEC_AH_SPI << 2) - 1)
+
+/*************************** IPSEC ESP fields ******************************/
+#define NH_FLD_IPSEC_ESP_SPI (1)
+#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM (NH_FLD_IPSEC_ESP_SPI << 1)
+#define NH_FLD_IPSEC_ESP_ALL_FIELDS ((NH_FLD_IPSEC_ESP_SPI << 2) - 1)
+
+#define NH_FLD_IPSEC_ESP_SPI_SIZE 4
+
+/*************************** MPLS fields ***********************************/
+#define NH_FLD_MPLS_LABEL_STACK (1)
+#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS \
+ ((NH_FLD_MPLS_LABEL_STACK << 1) - 1)
+
+/*************************** MACSEC fields *********************************/
+#define NH_FLD_MACSEC_SECTAG (1)
+#define NH_FLD_MACSEC_ALL_FIELDS ((NH_FLD_MACSEC_SECTAG << 1) - 1)
+
+/*************************** GTP fields ************************************/
+#define NH_FLD_GTP_TEID (1)
+
+/* Protocol options */
+
+/* Ethernet options */
+#define NH_OPT_ETH_BROADCAST 1
+#define NH_OPT_ETH_MULTICAST 2
+#define NH_OPT_ETH_UNICAST 3
+#define NH_OPT_ETH_BPDU 4
+
+#define NH_ETH_IS_MULTICAST_ADDR(addr) (addr[0] & 0x01)
+/* also applicable for broadcast */
+
+/* VLAN options */
+#define NH_OPT_VLAN_CFI 1
+
+/* IPV4 options */
+#define NH_OPT_IPV4_UNICAST 1
+#define NH_OPT_IPV4_MULTICAST 2
+#define NH_OPT_IPV4_BROADCAST 3
+#define NH_OPT_IPV4_OPTION 4
+#define NH_OPT_IPV4_FRAG 5
+#define NH_OPT_IPV4_INITIAL_FRAG 6
+
+/* IPV6 options */
+#define NH_OPT_IPV6_UNICAST 1
+#define NH_OPT_IPV6_MULTICAST 2
+#define NH_OPT_IPV6_OPTION 3
+#define NH_OPT_IPV6_FRAG 4
+#define NH_OPT_IPV6_INITIAL_FRAG 5
+
+/* General IP options (may be used for any version) */
+#define NH_OPT_IP_FRAG 1
+#define NH_OPT_IP_INITIAL_FRAG 2
+#define NH_OPT_IP_OPTION 3
+
+/* Minenc. options */
+#define NH_OPT_MINENCAP_SRC_ADDR_PRESENT 1
+
+/* GRE. options */
+#define NH_OPT_GRE_ROUTING_PRESENT 1
+
+/* TCP options */
+#define NH_OPT_TCP_OPTIONS 1
+#define NH_OPT_TCP_CONTROL_HIGH_BITS 2
+#define NH_OPT_TCP_CONTROL_LOW_BITS 3
+
+/* CAPWAP options */
+#define NH_OPT_CAPWAP_DTLS 1
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/*! IEEE8021.Q */
+#define NH_IEEE8021Q_ETYPE 0x8100
+#define NH_IEEE8021Q_HDR(etype, pcp, dei, vlan_id) \
+ ((((uint32_t)(etype & 0xFFFF)) << 16) | \
+ (((uint32_t)(pcp & 0x07)) << 13) | \
+ (((uint32_t)(dei & 0x01)) << 12) | \
+ (((uint32_t)(vlan_id & 0xFFF))))
+
+#endif /* __FSL_NET_H */
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 06/22] net/dpaa2: adding eth ops to dpaa2
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (4 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 05/22] net/dpaa2: add mc dpni object support Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
` (16 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/Makefile | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 410 ++++++++++++++++++++++++++++++++++++-
drivers/net/dpaa2/dpaa2_ethdev.h | 15 ++
4 files changed, 426 insertions(+), 1 deletion(-)
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/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 889181d..4350f45 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -49,6 +49,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
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 0b3dd67..5618feb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -47,32 +47,440 @@
#include <fslmc_logs.h>
#include <fslmc_vfio.h>
+#include <dpaa2_hw_pvt.h>
+
#include "dpaa2_ethdev.h"
static struct rte_dpaa2_driver rte_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)
+{
+ 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;
+}
+
+/* Function to setup RX flow information. It contains traffic class ID,
+ * flow ID, destination configuration etc.
+ */
+static int
+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",
+ ret, priv->hw_id);
+ 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;
+}
+
+/**
+ * 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,
+ .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
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 dpni_attr attr;
+ 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 = rte_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;
+ }
+
+ 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;
+
+ priv->hw = dpni_dev;
+ priv->hw_id = hw_id;
+ priv->flags = 0;
+
+ /* Allocate memory for hardware structure for queues */
+ 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 = rte_dpaa2_pmd.driver.name;
return 0;
}
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 5778780..5f599a7 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -34,11 +34,26 @@
#ifndef _DPAA2_ETHDEV_H
#define _DPAA2_ETHDEV_H
+#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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 07/22] net/dpaa2: add RSS flow distribution
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (5 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 06/22] net/dpaa2: adding eth ops to dpaa2 Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
` (15 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 4350f45..7f88e9b 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -58,6 +58,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
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 5618feb..61ce062 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -115,7 +115,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;
@@ -141,6 +142,7 @@
{
struct rte_eth_dev_data *data = dev->data;
struct rte_eth_conf *eth_conf = &data->dev_conf;
+ int ret;
PMD_INIT_FUNC_TRACE();
@@ -152,6 +154,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;
}
@@ -183,7 +197,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;
@@ -373,7 +387,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();
@@ -415,7 +429,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;
priv->hw = dpni_dev;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 08/22] net/dpaa2: configure MAC address at init
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (6 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 07/22] net/dpaa2: add RSS flow distribution Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
` (14 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 61ce062..21848ef 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -62,6 +62,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;
@@ -443,6 +444,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;
/* Allocate memory for hardware structure for queues */
@@ -452,6 +456,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 = rte_dpaa2_pmd.driver.name;
@@ -490,6 +513,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 09/22] net/dpaa2: attach the buffer pool to dpni
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (7 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 08/22] net/dpaa2: configure MAC address at init Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
` (13 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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/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 ++++
4 files changed, 127 insertions(+)
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 7f88e9b..1f66c0b 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -50,6 +50,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc
CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal
+CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
# versioning export map
@@ -63,5 +64,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_mempool_dpaa2
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 21848ef..c816076 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"
@@ -63,6 +64,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;
@@ -187,6 +190,7 @@
struct dpni_queue cfg;
uint8_t options = 0;
uint8_t flow_id;
+ uint32_t bpid;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -194,6 +198,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,
+ rte_dpaa2_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. */
@@ -388,7 +399,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();
@@ -475,6 +488,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 = rte_dpaa2_pmd.driver.name;
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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 10/22] net/dpaa2: add support for L3 and L4 checksum offload
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (8 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 09/22] net/dpaa2: attach the buffer pool to dpni Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
` (12 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 2 ++
drivers/net/dpaa2/dpaa2_ethdev.c | 72 +++++++++++++++++++++++++++++++++++---
2 files changed, 70 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c816076..f4565b6 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -68,7 +68,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;
@@ -252,8 +262,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);
@@ -302,6 +317,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;
@@ -337,6 +353,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;
}
@@ -453,7 +511,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);
priv->hw = dpni_dev;
priv->hw_id = hw_id;
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 11/22] net/dpaa2: add support for promiscuous mode
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (9 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 10/22] net/dpaa2: add support for L3 and L4 checksum offload Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
` (11 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 f4565b6..a3b7020 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -437,11 +437,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 12/22] net/dpaa2: add MTU configuration support
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (10 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 11/22] net/dpaa2: add support for promiscuous mode Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
` (10 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/nics/features/dpaa2.ini | 1 +
drivers/net/dpaa2/dpaa2_ethdev.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 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/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index a3b7020..e037bdb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -476,6 +476,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,
@@ -484,6 +517,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 13/22] net/dpaa2: enable packet Rx and Tx operations
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (11 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 12/22] net/dpaa2: add MTU configuration support Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
` (9 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
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 +++++++++++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index 1f66c0b..ce65542 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -60,6 +60,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
SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e037bdb..9c47c69 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -679,6 +679,8 @@
eth_dev->dev_ops = &dpaa2_ethdev_ops;
eth_dev->data->drv_name = rte_dpaa2_pmd.driver.name;
+ eth_dev->rx_pkt_burst = dpaa2_dev_rx;
+ eth_dev->tx_pkt_burst = dpaa2_dev_tx;
return 0;
}
@@ -732,6 +734,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..25574c0
--- /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),
+ rte_dpaa2_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),
+ rte_dpaa2_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),
+ rte_dpaa2_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)
+ - rte_dpaa2_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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 14/22] net/dpaa2: support for Rx packet parsing and packet type
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (12 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 13/22] net/dpaa2: enable packet Rx and Tx operations Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 15/22] net/dpaa2: link status update Hemant Agrawal
` (8 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 9c47c69..c92b865 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -310,6 +310,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)
{
@@ -517,6 +539,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 25574c0..c1ea33a 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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 15/22] net/dpaa2: link status update
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (13 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 14/22] net/dpaa2: support for Rx packet parsing and packet type Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 16/22] net/dpaa2: basic stats support Hemant Agrawal
` (7 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 c92b865..03d0e8c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -54,6 +54,58 @@
static struct rte_dpaa2_driver rte_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)
{
@@ -430,6 +482,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();
@@ -439,6 +492,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
@@ -531,6 +588,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,
@@ -538,6 +644,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 16/22] net/dpaa2: basic stats support
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (14 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 15/22] net/dpaa2: link status update Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
` (6 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 03d0e8c..157a2d0 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -588,6 +588,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,
@@ -645,6 +729,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 17/22] net/dpaa2: enable stashing for LS2088A devices
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (15 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 16/22] net/dpaa2: basic stats support Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
` (5 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
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 157a2d0..9cc8a46 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -277,6 +277,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 18/22] net/dpaa2: handle non-hardware backed buffer pool
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (16 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 17/22] net/dpaa2: enable stashing for LS2088A devices Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
` (4 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_rxtx.c | 75 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index c1ea33a..deec210 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -191,6 +191,55 @@ 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 (rte_dpaa2_mbuf_alloc_bulk(
+ rte_dpaa2_bpid_info[bpid].bp_list->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),
+ rte_dpaa2_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 +380,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->ops_index != priv->bp_list->dpaa2_ops_index) {
+ 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 +415,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 [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 19/22] net/dpaa2: enable physical addressing for packet buffers
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (17 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 18/22] net/dpaa2: handle non-hardware backed buffer pool Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
` (3 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 ++--
drivers/net/dpaa2/dpaa2_rxtx.c | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
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 deec210..c5d49cb 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)),
rte_dpaa2_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);
@@ -219,7 +220,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);
@@ -271,7 +272,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) {
@@ -312,7 +313,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)
- rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
/* Prefeth mbuf */
rte_prefetch0(mbuf);
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 20/22] config: add configuration for toggling physical addressing
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (18 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 19/22] net/dpaa2: enable physical addressing for packet buffers Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
` (2 subsequent siblings)
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
config/common_base | 1 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/common_base b/config/common_base
index 92bd9c9..412ec3f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -307,6 +307,7 @@ CONFIG_RTE_LIBRTE_FSLMC_BUS=n
# Compile Support Libraries for NXP DPAA2
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile burst-oriented NXP DPAA2 PMD driver
diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
index 6e8f6fd..174c0ed 100644
--- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
+++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
@@ -49,6 +49,7 @@ CONFIG_RTE_PKTMBUF_HEADROOM=256
#
CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
#
# Compile NXP DPAA2 FSL-MC Bus
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 21/22] net/dpaa2: enable DMA Mapping during device scanning
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (19 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 20/22] config: add configuration for toggling physical addressing Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
2017-04-12 13:52 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Ferruh Yigit
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 9cc8a46..999d0ad 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -908,6 +908,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;
+ rte_fslmc_vfio_dmamap();
+
return 0;
}
--
1.9.1
^ permalink raw reply [flat|nested] 549+ messages in thread
* [dpdk-dev] [PATCH v12 22/22] net/dpaa2: enable frame queue based dequeuing
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (20 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 21/22] net/dpaa2: enable DMA Mapping during device scanning Hemant Agrawal
@ 2017-04-11 13:49 ` Hemant Agrawal
2017-04-12 13:52 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Ferruh Yigit
22 siblings, 0 replies; 549+ messages in thread
From: Hemant Agrawal @ 2017-04-11 13:49 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
ferruh.yigit, jerin.jacob
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 999d0ad..4576442 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"
@@ -169,9 +170,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++) {
@@ -195,7 +195,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 [flat|nested] 549+ messages in thread
* Re: [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 00/22] NXP DPAA2 PMD Hemant Agrawal
` (21 preceding siblings ...)
2017-04-11 13:49 ` [dpdk-dev] [PATCH v12 22/22] net/dpaa2: enable frame queue based dequeuing Hemant Agrawal
@ 2017-04-12 13:52 ` Ferruh Yigit
22 siblings, 0 replies; 549+ messages in thread
From: Ferruh Yigit @ 2017-04-12 13:52 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas.monjalon, bruce.richardson, shreyansh.jain, john.mcnamara,
jerin.jacob
On 4/11/2017 2:49 PM, Hemant Agrawal wrote:
> This patches has been split from DPAA2 PMD v8 series [2] as per
> comments received on ML [3].)
>
> The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
> network SoC PMD. This version of the driver supports NXP LS208xA,
> LS204xA and LS108x families Network SoCs.
>
> DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
> designed for high-speed network packet processing. It uses a bus name
> ‘fslmc’, part of Linux Kernel Staging tree [1], for resource management.
>
> Dependency:
> This patchset is to be applied over
> a) NXP DPAA2 FSLMC Bus Patches [4] and
> b) NXP DPAA2 Mempool patches [5]
>
> Prerequisites:
> - For running the PMD, NXP's SoC (board) is required.
> Information about obtaining relevant software is available in the docs
> as part of the patch.
>
> References:
> [1] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
> [2] http://dpdk.org/ml/archives/dev/2017-March/059000.html
> [3] http://dpdk.org/ml/archives/dev/2017-March/059789.html
> [4] http://dpdk.org/ml/archives/dev/2017-April/063683.html
> [5] http://dpdk.org/ml/archives/dev/2017-April/063707.html
>
> ---
> v12:
> * Rebased on net-next & patchset [4] & [5]
> * removing config dependency.
>
> v11:
> * Rebased on master (17.05-rc1) & patchset [4] & [5]
>
> v10:
> * Rebased on next-net (b36be54c)
> * Removing "-Wno-strict-alias" from makefile
>
> v9:
> * Split into three series: 1) for FSLMC Bus, 2) Mempool and 3) PMD
> * Rebased over master (17.02, 630f6ec1)
> * remove the eth_driver usages
>
> v8:
> * rebased over master (17.02: 35b09d76)
> * Removed all drivers/common/* code and moved to drivers/bus/fslmc
> * Updated documentation to remove non-open source dependency
> * Reduced shared symbols in map files
>
> v7:
> * rebased over master (17.02)
> * fix the shared lib compilation
> * re partitiion the patches as per Ferruh comments.
> * handling Ferruh's comment for NXP dpaa2 driver
>
> v6:
> * rebased over master (61207d0)
> * removing DPAA2_COMMON as configurable option
> * renaming drivers bus, pool libraries removing 'pmd'
> * Headers of Licenses
> * exposed variable renaming with *rte_* prefix
> * handling Ferruh's comment for NXP dpaa2 driver
> * moving around MAINTAINER and DOC file patches
>
> v5:
> * rebased over master (6818a7f4)
>
> v4:
> * rebased over master (1feda4d8) and patches from Shreyansh [1] for Bus Arch.
>
> v3:
> * rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
> * Fixed comment from John on Patch-0003 for documentation
> * Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
> another series
>
> v2:
> * separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
> * separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
> * removed documentation warnings and missing information.
> * removed arm64 part specific code from driver
> * changed rte_panic to errors
> * reduced checkpatch warnings
>
> Hemant Agrawal (22):
> net/dpaa2: introducing NXP DPAA2 PMD driver
> doc: add DPAA2 NIC details
> net/dpaa2: add debug log support
> config: enable support for DPAA2 debug logging
> net/dpaa2: add mc dpni object support
> net/dpaa2: adding eth ops to dpaa2
> net/dpaa2: add RSS flow distribution
> net/dpaa2: configure MAC address at init
> net/dpaa2: attach the buffer pool to dpni
> net/dpaa2: add support for L3 and L4 checksum offload
> net/dpaa2: add support for promiscuous mode
> net/dpaa2: add MTU configuration support
> net/dpaa2: enable packet Rx and Tx operations
> net/dpaa2: support for Rx packet parsing and packet type
> net/dpaa2: link status update
> net/dpaa2: basic stats support
> net/dpaa2: enable stashing for LS2088A devices
> net/dpaa2: handle non-hardware backed buffer pool
> net/dpaa2: enable physical addressing for packet buffers
> config: add configuration for toggling physical addressing
> net/dpaa2: enable DMA Mapping during device scanning
> net/dpaa2: enable frame queue based dequeuing
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 549+ messages in thread