DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver
@ 2018-04-07 15:16 Nipun Gupta
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
                   ` (10 more replies)
  0 siblings, 11 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:16 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is based over v2 of DPAA2 CMDIF series -
https://dpdk.org/dev/patchwork/patch/35337/

Patches 1-3:
  Makes necessary changes in the DPAA2 bus
Patches 4-6:
  Add the DPAA2 QDMA driver
Patches 7-8:
  Update the respective documentation

Nipun Gupta (8):
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide
  doc: add dpaa2 qdma rawdev to release notes

 MAINTAINERS                                        |   6 +
 config/common_base                                 |   1 +
 config/common_linuxapp                             |   1 +
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  | 140 +++
 doc/guides/rel_notes/release_18_05.rst             |   9 +
 drivers/bus/fslmc/Makefile                         |   3 +-
 drivers/bus/fslmc/fslmc_bus.c                      |   2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |   1 +
 drivers/bus/fslmc/mc/dpdmai.c                      | 429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  | 189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              | 107 +++
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |   3 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |   9 +
 drivers/bus/fslmc/rte_fslmc.h                      |   2 +
 drivers/raw/Makefile                               |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |  36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 997 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                | 150 ++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  33 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  20 +
 mk/rte.app.mk                                      |   1 +
 24 files changed, 2427 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

-- 
1.9.1

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

* [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-04-07 15:16 ` Nipun Gupta
  2018-04-16 11:46   ` Shreyansh Jain
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:16 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   3 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 5 files changed, 736 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 93870ba..072a23a 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -37,7 +37,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
         mc/dpio.c \
         mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..03ce2a7
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..a502676
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..4d4d439
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 3811792..d433714 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,6 +105,15 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 	rte_dpaa2_free_dpci_dev;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-04-07 15:16 ` Nipun Gupta
  2018-04-16 11:58   ` Shreyansh Jain
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:16 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index d6806df..cd27630 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 62499de..6708ad8 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -554,6 +554,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..a454ef5 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< DPAA2 raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-04-07 15:16 ` Nipun Gupta
  2018-04-16 12:23   ` Shreyansh Jain
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:16 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1ef9502..b7b98d1 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -212,10 +212,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -225,6 +227,7 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_ERR(fd)	((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FD_FRC(fd)	((fd)->simple.frc)
 #define DPAA2_GET_FD_FLC(fd) \
 	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
-- 
1.9.1

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

* [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (2 preceding siblings ...)
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-07 15:17 ` Nipun Gupta
  2018-04-16 13:46   ` Shreyansh Jain
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 5/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:17 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                                        |   5 +
 config/common_base                                 |   1 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 290 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  33 +++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 mk/rte.app.mk                                      |   1 +
 10 files changed, 436 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ef5902..fccf5bb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -772,6 +772,11 @@ F: drivers/event/opdl/
 F: doc/guides/eventdevs/opdl.rst
 
 
+DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Packet processing
 -----------------
 
diff --git a/config/common_base b/config/common_base
index 9c4361f..956fbc1 100644
--- a/config/common_base
+++ b/config/common_base
@@ -192,6 +192,7 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=n
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=n
 
 #
 # Compile burst-oriented Amazon ENA PMD driver
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f25b3ea..0c6a1ce 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index de3e662..7b5dcc3 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
 ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF) += dpaa2_cmdif
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma
 endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..f81ee08
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..4b7fa13
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops = {
+};
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue\n");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static int
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	while ((queue = TAILQ_FIRST(&qdma_queue_list))) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+		}
+	}
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d\n", ret);
+		return ret;
+	}
+	DPAA2_QDMA_DEBUG("Opened dpdmai object successfully\n");
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d\n",
+			       ret);
+		return ret;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			return ret;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed\n");
+			return -ENOMEM;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed\n");
+			return -ENOMEM;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			return ret;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			return ret;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		dpaa2_free_dq_storage(rxq->q_storage);
+		rte_free(rxq->q_storage);
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice\n");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_DEBUG("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..20902a8
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	DPAA2_QDMA_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..9b9ab1a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+DPDK_18.05 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a6828c8..f2c778f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -118,6 +118,7 @@ endif
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA_BUS)       += -lrte_bus_dpaa
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += -lrte_pmd_dpaa2_qdma
 ifeq ($(CONFIG_RTE_EAL_VFIO),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS)      += -lrte_bus_fslmc
 endif
-- 
1.9.1

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

* [dpdk-dev] [PATCH 5/8] raw/dpaa2_qdma: support configuration APIs
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (3 preceding siblings ...)
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-07 15:17 ` Nipun Gupta
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:17 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 7 files changed, 670 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index b9f28be..c0b5653 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -65,6 +65,7 @@ The public API headers are grouped by topics:
   [dpaa]               (@ref rte_pmd_dpaa.h),
   [dpaa2]              (@ref rte_dpaa2_mempool.h),
   [dpaa2_cmdif]        (@ref rte_pmd_dpaa2_cmdif.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 88088d6..0840b34 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -39,6 +39,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
                           drivers/raw/dpaa2_cmdif \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index f81ee08..6711df3 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 4b7fa13..b5f6bd9 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.\n");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d\n", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.\n");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed\n");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d\n",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed\n");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed\n");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq\n");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ\n");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops = {
 };
 
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..d27fd49
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 9b9ab1a..0a0d3c5 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 DPDK_18.05 {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (4 preceding siblings ...)
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 5/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-04-07 15:17 ` Nipun Gupta
  2018-04-16 14:01   ` Shreyansh Jain
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:17 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 332 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 427 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b5f6bd9..5cd18ec 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,338 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd = {};
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal\n");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_ERR("Memory alloc failed for FLE\n");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d\n", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DEBUG("Successfully transmitted a packet\n");
+
+	return ret;
+}
+
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_WARN("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d\n", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal\n");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(dma_addr_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_WARN("VDQ command not issued. QBMAN busy\n");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DEBUG("No frame is delivered\n");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DEBUG("packet received\n");
+
+	return 1;
+}
+
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_WARN("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusine queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d\n", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index d27fd49..5a0ee4e 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 0a0d3c5..59dd27c 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ DPDK_18.05 {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (5 preceding siblings ...)
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-04-07 15:17 ` Nipun Gupta
  2018-04-16 14:04   ` Shreyansh Jain
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 8/8] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:17 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                       |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst | 140 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 141 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index fccf5bb..6eb6d98 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -775,6 +775,7 @@ F: doc/guides/eventdevs/opdl.rst
 DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Packet processing
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..211b716
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.dpaa2.qdma,<level>
+
+Using ``dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
-- 
1.9.1

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

* [dpdk-dev] [PATCH 8/8] doc: add dpaa2 qdma rawdev to release notes
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (6 preceding siblings ...)
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-04-07 15:17 ` Nipun Gupta
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-07 15:17 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/guides/rel_notes/release_18_05.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0aebb18..f2de969 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -66,6 +66,15 @@ New Features
 
   See the :doc:`../rawdevs/dpaa2_cmdif.rst` guide for more details.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma.rst` guide for more details.
+
+
 API Changes
 -----------
 
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-04-16 11:46   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 11:46 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: thomas, hemant.agrawal, dev, Cristian Sovaiala

On Saturday 07 April 2018 08:46 PM, Nipun Gupta wrote:
> This patch adds the DPDMAI (Data Path DMA Interface)
> object support in MC driver.
> 
> Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/bus/fslmc/Makefile                  |   3 +-
>   drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
>   drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
>   drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
>   drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
>   5 files changed, 736 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
>   create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
>   create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
> 

Once rebased on master:

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

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

* Re: [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-04-16 11:58   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 11:58 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: thomas, hemant.agrawal, dev

On Saturday 07 April 2018 08:46 PM, Nipun Gupta wrote:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/bus/fslmc/fslmc_bus.c  | 2 ++
>   drivers/bus/fslmc/fslmc_vfio.c | 1 +
>   drivers/bus/fslmc/rte_fslmc.h  | 2 ++
>   3 files changed, 5 insertions(+)
> 

[...]
Can you please explain, in the commit message, the relation between 
'DPDMAI' and 'QDMA' devices? Your patch has both these tokens.

> diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
> index 69d0fec..a454ef5 100644
> --- a/drivers/bus/fslmc/rte_fslmc.h
> +++ b/drivers/bus/fslmc/rte_fslmc.h
> @@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
>   	DPAA2_IO,	/**< DPIO type device */
>   	DPAA2_CI,	/**< DPCI type device */
>   	DPAA2_MPORTAL,  /**< DPMCP type device */
> +	DPAA2_QDMA,     /**< DPDMAI type device */
>   	/* Unknown device placeholder */
>   	DPAA2_UNKNOWN,
>   	DPAA2_DEVTYPE_MAX,
> @@ -91,6 +92,7 @@ struct rte_dpaa2_device {
>   	union {
>   		struct rte_eth_dev *eth_dev;        /**< ethernet device */
>   		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
> +		struct rte_rawdev *rawdev;          /**< DPAA2 raw Device */
                                                 /'''''''^^^^^^
                     just a 'Raw device' please./

>   	};
>   	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
>   	uint16_t object_id;                 /**< DPAA2 Object ID */
> 

Just the trivial issues noted above and after rebasing on master, please 
use:

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

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

* Re: [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-07 15:16 ` [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-16 12:23   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 12:23 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: thomas, hemant.agrawal, dev

On Saturday 07 April 2018 08:46 PM, Nipun Gupta wrote:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
> index 1ef9502..b7b98d1 100644
> --- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
> +++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
> @@ -212,10 +212,12 @@ enum qbman_fd_format {

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

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

* Re: [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-16 13:46   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 13:46 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev

On Saturday 07 April 2018 08:47 PM, Nipun Gupta wrote:
> DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
> the user (app) to perform data DMA without involving CPU in
> the DMA process
> 
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   MAINTAINERS                                        |   5 +
>   config/common_base                                 |   1 +
>   config/common_linuxapp                             |   1 +
>   drivers/raw/Makefile                               |   1 +
>   drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 290 +++++++++++++++++++++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  33 +++
>   .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
>   mk/rte.app.mk                                      |   1 +
>   10 files changed, 436 insertions(+)
>   create mode 100644 drivers/raw/dpaa2_qdma/Makefile
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
>   create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> 

[...]

> diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> new file mode 100644
> index 0000000..4b7fa13
> --- /dev/null
> +++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> @@ -0,0 +1,290 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2018 NXP
> + */
> +
> +#include <string.h>
> +
> +#include <rte_eal.h>
> +#include <rte_fslmc.h>
> +#include <rte_atomic.h>
> +#include <rte_lcore.h>
> +#include <rte_rawdev.h>
> +#include <rte_rawdev_pmd.h>
> +#include <rte_malloc.h>
> +#include <rte_ring.h>
> +#include <rte_mempool.h>
> +
> +#include <mc/fsl_dpdmai.h>
> +#include <portal/dpaa2_hw_pvt.h>
> +#include <portal/dpaa2_hw_dpio.h>
> +
> +#include "dpaa2_qdma.h"
> +#include "dpaa2_qdma_logs.h"
> +
> +/* Dynamic log type identifier */
> +int dpaa2_qdma_logtype;
> +
> +/* QDMA device */
> +static struct qdma_device qdma_dev;
> +
> +/* QDMA H/W queues list */
> +TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
> +static struct qdma_hw_queue_list qdma_queue_list
> +	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
> +
> +static const struct rte_rawdev_ops dpaa2_qdma_ops = {
> +};
> +
> +static int
> +add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
> +{
> +	struct qdma_hw_queue *queue;
> +	int i;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	for (i = 0; i < dpdmai_dev->num_queues; i++) {
> +		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
> +		if (!queue) {
> +			DPAA2_QDMA_ERR(
> +				"Memory allocation failed for QDMA queue\n");

I think the definition of DPAA2_QDMA_ERR also contains an inbuilt '\n' - 
so, it would be double new lines. And this is valid at various other 
places in this patch.

> +			return -ENOMEM;
> +		}
> +
> +		queue->dpdmai_dev = dpdmai_dev;
> +		queue->queue_id = i;
> +
> +		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
> +		qdma_dev.num_hw_queues++;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
> +{
> +	struct qdma_hw_queue *queue;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	while ((queue = TAILQ_FIRST(&qdma_queue_list))) {

I think you might want to revisit this. TAILQ_FIRST will keep returning 
you the head of the list. TAILQ_FOREACH_SAFE is what you should be 
looking at.

> +		if (queue->dpdmai_dev == dpdmai_dev) {
> +			TAILQ_REMOVE(&qdma_queue_list, queue, next);
> +			rte_free(queue);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
> +{
> +	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
> +	struct dpdmai_rx_queue_cfg rx_queue_cfg;
> +	struct dpdmai_attr attr;
> +	struct dpdmai_rx_queue_attr rx_attr;
> +	struct dpdmai_tx_queue_attr tx_attr;
> +	int ret, i;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	/* Open DPDMAI device */
> +	dpdmai_dev->dpdmai_id = dpdmai_id;
> +	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
> +	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
> +	if (ret) {
> +		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d\n", ret);
> +		return ret;
> +	}
> +	DPAA2_QDMA_DEBUG("Opened dpdmai object successfully\n");
> +
> +	/* Get DPDMAI attributes */
> +	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +				    dpdmai_dev->token, &attr);
> +	if (ret) {
> +		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d\n",
> +			       ret);

Should dpdmai_close be called here? In case there is some state managed 
in the device which might impact its opening next time.
This would be valid for various errors generated in this function.

> +		return ret;
> +	}
> +	dpdmai_dev->num_queues = attr.num_of_priorities;
> +
> +	/* Set up Rx Queues */
> +	for (i = 0; i < attr.num_of_priorities; i++) {
> +		struct dpaa2_queue *rxq;
> +
> +		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
> +		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
> +					  CMD_PRI_LOW,
> +					  dpdmai_dev->token,
> +					  i, &rx_queue_cfg);
> +		if (ret) {
> +			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
> +				       ret);
> +			return ret;
> +		}
> +
> +		/* Allocate DQ storage for the DPDMAI Rx queues */
> +		rxq = &(dpdmai_dev->rx_queue[i]);
> +		rxq->q_storage = rte_malloc("dq_storage",
> +					    sizeof(struct queue_storage_info_t),
> +					    RTE_CACHE_LINE_SIZE);
> +		if (!rxq->q_storage) {
> +			DPAA2_QDMA_ERR("q_storage allocation failed\n");
> +			return -ENOMEM;
> +		}
> +
> +		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
> +		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
> +		if (ret) {
> +			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed\n");
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	/* Get Rx and Tx queues FQID's */
> +	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
> +		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +					  dpdmai_dev->token, i, &rx_attr);
> +		if (ret) {
> +			DPAA2_QDMA_ERR("Reading device failed with err: %d",
> +				       ret);
> +			return ret;
> +		}
> +		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
> +
> +		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +					  dpdmai_dev->token, i, &tx_attr);
> +		if (ret) {
> +			DPAA2_QDMA_ERR("Reading device failed with err: %d",
> +				       ret);
> +			return ret;
> +		}
> +		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
> +	}
> +
> +	/* Enable the device */
> +	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +			    dpdmai_dev->token);
> +	if (ret) {
> +		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
> +		return ret;
> +	}
> +
> +	/* Add the HW queue to the global list */
> +	ret = add_hw_queues_to_list(dpdmai_dev);
> +	if (ret) {
> +		DPAA2_QDMA_ERR("Adding H/W queue to list failed\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
> +{
> +	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
> +	int ret, i;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +		return 0;
> +
> +	/* Remove HW queues from global list */
> +	remove_hw_queues_from_list(dpdmai_dev);
> +
> +	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
> +			     dpdmai_dev->token);
> +	if (ret)
> +		DPAA2_QDMA_ERR("dmdmai disable failed");
> +
> +	/* Set up the DQRR storage for Rx */
> +	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
> +		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
> +
> +		dpaa2_free_dq_storage(rxq->q_storage);
> +		rte_free(rxq->q_storage);
> +	}
> +
> +	/* Close the device at underlying layer*/
> +	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
> +	if (ret)
> +		DPAA2_QDMA_ERR("Failure closing dpdmai device");
> +
> +	return 0;
> +}
> +
> +static int
> +rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
> +		     struct rte_dpaa2_device *dpaa2_dev)
> +{
> +	struct rte_rawdev *rawdev;
> +	int ret;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
> +			sizeof(struct dpaa2_dpdmai_dev),
> +			rte_socket_id());
> +	if (!rawdev) {
> +		DPAA2_QDMA_ERR("Unable to allocate rawdevice\n");
> +		return -EINVAL;
> +	}
> +
> +	dpaa2_dev->rawdev = rawdev;
> +	rawdev->dev_ops = &dpaa2_qdma_ops;
> +	rawdev->device = &dpaa2_dev->device;
> +	rawdev->driver_name = dpaa2_drv->driver.name;
> +
> +	/* For secondary processes, the primary has done all the work */
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +		return 0;
> +
> +	/* Invoke PMD device initialization function */
> +	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
> +	if (ret) {
> +		rte_rawdev_pmd_release(rawdev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
> +{
> +	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
> +	int ret;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	dpaa2_dpdmai_dev_uninit(rawdev);
> +
> +	ret = rte_rawdev_pmd_release(rawdev);
> +	if (ret)
> +		DPAA2_QDMA_DEBUG("Device cleanup failed");
> +
> +	return 0;
> +}
> +
> +static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
> +	.drv_type = DPAA2_QDMA,
> +	.probe = rte_dpaa2_qdma_probe,
> +	.remove = rte_dpaa2_qdma_remove,
> +};
> +
> +RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
> +
> +RTE_INIT(dpaa2_qdma_init_log);
> +

It is better to not add a new line here - that we we can relate the 
function below with the INIT macro above.

> +static void
> +dpaa2_qdma_init_log(void)
> +{
> +	dpaa2_qdma_logtype = rte_log_register("dpaa2.qdma");

The string for registeration should be of format 
'pmd.raw.<driver>.<feature>'.
See SHA: 7db274b9ada2221acb7110204a3b2c6a37d2614a for documentation.

> +	if (dpaa2_qdma_logtype >= 0)
> +		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
> +}

[...]

> +#endif /* __DPAA2_QDMA_H__ */
> diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
> new file mode 100644
> index 0000000..20902a8
> --- /dev/null
> +++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2018 NXP
> + */
> +
> +#ifndef __DPAA2_QDMA_LOGS_H__
> +#define __DPAA2_QDMA_LOGS_H__
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +extern int dpaa2_qdma_logtype;
> +
> +#define DPAA2_QDMA_LOG(level, fmt, args...) \
> +	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "%s(): " fmt "\n", \
> +		__func__, ##args)

Some logs don't need to have a function name associated with them in 
output - especially the error messages. All the macros here have 
'__func__'  as part of the output. Can you rethink if this is OK with you?

> +
> +#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
> +
> +#define DPAA2_QDMA_DEBUG(fmt, args...) \
> +	DPAA2_QDMA_LOG(DEBUG, fmt, ## args)
> +#define DPAA2_QDMA_INFO(fmt, args...) \
> +	DPAA2_QDMA_LOG(INFO, fmt, ## args)
> +#define DPAA2_QDMA_ERR(fmt, args...) \
> +	DPAA2_QDMA_LOG(ERR, fmt, ## args)
> +#define DPAA2_QDMA_WARN(fmt, args...) \
> +	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* __DPAA2_QDMA_LOGS_H__ */
> diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> new file mode 100644
> index 0000000..9b9ab1a
> --- /dev/null
> +++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> @@ -0,0 +1,4 @@
> +DPDK_18.05 {
> +
> +	local: *;
> +};
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index a6828c8..f2c778f 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -118,6 +118,7 @@ endif
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA_BUS)       += -lrte_bus_dpaa
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += -lrte_pmd_dpaa2_qdma

This shouldn't be placed between the bus linking instructions. Maybe 
somewhere near the other rawdev PMD would be better.

>   ifeq ($(CONFIG_RTE_EAL_VFIO),y)
>   _LDLIBS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS)      += -lrte_bus_fslmc
>   endif
> 

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

* Re: [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-04-16 14:01   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 14:01 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev

On Saturday 07 April 2018 08:47 PM, Nipun Gupta wrote:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 332 +++++++++++++++++++++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
>   drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
>   .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
>   4 files changed, 427 insertions(+)
> 
> diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> index b5f6bd9..5cd18ec 100644
> --- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> +++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> @@ -344,6 +344,338 @@
>   	return i;
>   }
>   
> +static void
> +dpaa2_qdma_populate_fle(struct qbman_fle *fle,
> +			uint64_t src, uint64_t dest,
> +			size_t len, uint32_t flags)
> +{
> +	struct qdma_sdd *sdd;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
> +		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
> +
> +	/* first frame list to source descriptor */
> +	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
> +	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
> +
> +	/* source and destination descriptor */
> +	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
> +	sdd++;
> +	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
> +
> +	fle++;
> +	/* source frame list to source buffer */
> +	if (flags & RTE_QDMA_JOB_SRC_PHY) {
> +		DPAA2_SET_FLE_ADDR(fle, src);
> +		DPAA2_SET_FLE_BMT(fle);
> +	} else {
> +		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
> +	}
> +	DPAA2_SET_FLE_LEN(fle, len);
> +
> +	fle++;
> +	/* destination frame list to destination buffer */
> +	if (flags & RTE_QDMA_JOB_DEST_PHY) {
> +		DPAA2_SET_FLE_BMT(fle);
> +		DPAA2_SET_FLE_ADDR(fle, dest);
> +	} else {
> +		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
> +	}
> +	DPAA2_SET_FLE_LEN(fle, len);
> +
> +	/* Final bit: 1, for last frame list */
> +	DPAA2_SET_FLE_FIN(fle);
> +}
> +
> +static int
> +dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
> +		   uint16_t txq_id,
> +		   uint16_t vq_id,
> +		   struct rte_qdma_job *job)
> +{
> +	struct qdma_io_meta *io_meta;
> +	struct qbman_fd fd = {};
> +	struct dpaa2_queue *txq;
> +	struct qbman_fle *fle;
> +	struct qbman_eq_desc eqdesc;
> +	struct qbman_swp *swp;
> +	int ret;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
> +		ret = dpaa2_affine_qbman_swp();
> +		if (ret) {
> +			DPAA2_QDMA_ERR("Failure in affining portal\n");
> +			return 0;
> +		}
> +	}
> +	swp = DPAA2_PER_LCORE_PORTAL;
> +
> +	txq = &(dpdmai_dev->tx_queue[txq_id]);
> +
> +	/* Prepare enqueue descriptor */
> +	qbman_eq_desc_clear(&eqdesc);
> +	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
> +	qbman_eq_desc_set_no_orp(&eqdesc, 0);
> +	qbman_eq_desc_set_response(&eqdesc, 0, 0);
> +
> +	/*
> +	 * Get an FLE/SDD from FLE pool.
> +	 * Note: IO metadata is before the FLE and SDD memory.
> +	 */
> +	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
> +	if (ret) {
> +		DPAA2_QDMA_ERR("Memory alloc failed for FLE\n");
> +		return ret;
> +	}
> +
> +	/* Set the metadata */
> +	io_meta->cnxt = (size_t)job;
> +	io_meta->id = vq_id;
> +
> +	fle = (struct qbman_fle *)(io_meta + 1);
> +
> +	/* populate Frame descriptor */
> +	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
> +	DPAA2_SET_FD_COMPOUND_FMT(&fd);
> +	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
> +
> +	/* Populate FLE */
> +	memset(fle, 0, QDMA_FLE_POOL_SIZE);
> +	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
> +
> +	/* Enqueue the packet to the QBMAN */
> +	do {
> +		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
> +		if (ret < 0 && ret != -EBUSY)
> +			DPAA2_QDMA_ERR("Transmit failure with err: %d\n", ret);

Similar comment to one of the other patch - your macro definition has 
'\n' already in it. So, double new lines.

> +	} while (ret == -EBUSY);
> +
> +	DPAA2_QDMA_DEBUG("Successfully transmitted a packet\n");

Macros like the above are compiled into the code unlike the DP_ 
variants. If this is I/O path and such conditionals impact performance, 
maybe DP_ variant would be more efficient.

> +
> +	return ret;
> +}
> +
> +int
> +rte_qdma_vq_enqueue_multi(uint16_t vq_id,
> +			  struct rte_qdma_job **job,
> +			  uint16_t nb_jobs)
> +{
> +	int i, ret;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	for (i = 0; i < nb_jobs; i++) {
> +		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
> +		if (ret < 0)
> +			break;
> +	}
> +
> +	return i;
> +}
> +
> +int
> +rte_qdma_vq_enqueue(uint16_t vq_id,
> +		    struct rte_qdma_job *job)
> +{
> +	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
> +	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
> +	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
> +	int ret;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	/* Return error in case of wrong lcore_id */
> +	if (rte_lcore_id() != qdma_vq->lcore_id) {
> +		DPAA2_QDMA_WARN("QDMA enqueue for vqid %d on wrong core",
                /^^^^^^^^^^^^^^^
               /
Should this be DPAA2_QDMA_ERR?

> +				vq_id);
> +		return -EINVAL;
> +	}
> +
> +	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
> +	if (ret < 0) {
> +		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	qdma_vq->num_enqueues++;
> +
> +	return 1;
> +}
> +

[...]

> +
> +struct rte_qdma_job *
> +rte_qdma_vq_dequeue(uint16_t vq_id)
> +{
> +	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
> +	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
> +	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
> +	struct rte_qdma_job *job = NULL;
> +	struct qdma_virt_queue *temp_qdma_vq;
> +	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
> +	int ring_count, ret, i;
> +	uint16_t temp_vq_id;
> +
> +	DPAA2_QDMA_FUNC_TRACE();
> +
> +	/* Return error in case of wrong lcore_id */
> +	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
> +		DPAA2_QDMA_WARN("QDMA dequeue for vqid %d on wrong core",
> +				vq_id);
> +		return NULL;
> +	}
> +
> +	/* Only dequeue when there are pending jobs on VQ */
> +	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
> +		return NULL;
> +
> +	if (qdma_vq->exclusive_hw_queue) {
> +		/* In case of exclusine queue directly fetch from HW queue */

for above comment s/exclusine/exclusive/

[...]

-
Shreyansh

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

* Re: [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-04-16 14:04   ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-16 14:04 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev

On Saturday 07 April 2018 08:47 PM, Nipun Gupta wrote:

[...]

> +  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
> +
> +Enabling logs
> +-------------
> +
> +For enabling logs, use the following EAL parameter:
> +
> +.. code-block:: console
> +
> +   ./your_qdma_application <EAL args> --log-level=pmd.dpaa2.qdma,<level>

You will have to change/confirm the log-level string above. There is a 
comment on one of the patch defining this string.

> +
> +Using ``dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
> +enabled which are lower than logging ``level``.
> +
> +Driver Compilation
> +~~~~~~~~~~~~~~~~~~

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

* [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (7 preceding siblings ...)
  2018-04-07 15:17 ` [dpdk-dev] [PATCH 8/8] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
@ 2018-04-20  4:04 ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 1/9 v2] bus/fslmc: support MC DPDMAI object Nipun Gupta
                     ` (9 more replies)
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
  10 siblings, 10 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patches 1-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patches 8-9:
  Update the respective documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Nipun Gupta (9):
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  bus/fslmc: fix typecasting in IOVA/virt conversion macros
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide
  doc: add dpaa2 qdma rawdev to release notes

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    1 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |   12 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/raw/Makefile                               |    4 +
 drivers/raw/dpaa2_qdma/Makefile                    |   36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 mk/rte.app.mk                                      |    3 +
 26 files changed, 2476 insertions(+), 7 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

-- 
1.9.1

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

* [dpdk-dev] [PATCH 1/9 v2] bus/fslmc: support MC DPDMAI object
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 2/9 v2] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 5 files changed, 739 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 2/9 v2] bus/fslmc: support scanning and probing of QDMA devices
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 1/9 v2] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index d0b3261..a3898b5 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 675d160..44d4cba 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 1/9 v2] bus/fslmc: support MC DPDMAI object Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 2/9 v2] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  9:17     ` Hemant Agrawal
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 4/9 v2] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 72aae43..1b67bed 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH 4/9 v2] bus/fslmc: fix typecasting in IOVA/virt conversion macros
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (2 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 5/9 v2] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta, stable

Fixes: df0011c92312 ("bus/fslmc: add physical-virtual address translation helpers")
Cc: stable@dpdk.org

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1b67bed..507bff7 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -316,8 +316,8 @@ static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr)
 
 #define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_addr)
 #define DPAA2_OP_VADDR_TO_IOVA(op) (op)
-#define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr)
-#define DPAA2_IOVA_TO_VADDR(_iova) (_iova)
+#define DPAA2_VADDR_TO_IOVA(_vaddr) ((phys_addr_t)(_vaddr))
+#define DPAA2_IOVA_TO_VADDR(_iova) ((void *)(_iova))
 #define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type)
 
 #endif /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 5/9 v2] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (3 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 4/9 v2] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 6/9 v2] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   1 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   4 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 295 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 mk/rte.app.mk                                      |   3 +
 10 files changed, 462 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index f43e3fe..dc226d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -773,6 +773,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index c2b0d91..ed957db 100644
--- a/config/common_base
+++ b/config/common_base
@@ -210,6 +210,7 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 #
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=n
 
 #
 # Compile burst-oriented Amazon ENA PMD driver
diff --git a/config/common_linuxapp b/config/common_linuxapp
index d0437e5..99fb25a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -37,3 +37,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..b563fc8 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma
+endif
+
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..f81ee08
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9c5b0bc
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,295 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops = {
+};
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..9b9ab1a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+DPDK_18.05 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8bab901..888b12f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -246,6 +246,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH 6/9 v2] raw/dpaa2_qdma: support configuration APIs
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (4 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 5/9 v2] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 7/9 v2] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 7 files changed, 670 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ad8bdcf..18a7ed4 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index f81ee08..6711df3 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9c5b0bc..2325a8d 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops = {
 };
 
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..d27fd49
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 9b9ab1a..0a0d3c5 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 DPDK_18.05 {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH 7/9 v2] raw/dpaa2_qdma: support enq and deq operations
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (5 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 6/9 v2] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 8/9 v2] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 332 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 427 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 2325a8d..df5fe7c 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,338 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd = {};
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(dma_addr_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index d27fd49..5a0ee4e 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 0a0d3c5..59dd27c 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ DPDK_18.05 {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 8/9 v2] doc: add DPAA2 QDMA rawdev guide
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (6 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 7/9 v2] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 9/9 v2] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
  2018-04-20  4:10   ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                       |   1 +
 doc/guides/index.rst              |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst | 140 ++++++++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst      |  14 ++++
 4 files changed, 156 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index dc226d8..d6f9a4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -779,6 +779,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..d460f24
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
-- 
1.9.1

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

* [dpdk-dev] [PATCH 9/9 v2] doc: add dpaa2 qdma rawdev to release notes
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (7 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 8/9 v2] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-04-20  4:04   ` Nipun Gupta
  2018-04-20  4:10   ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:04 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/guides/rel_notes/release_18_05.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index bc9cdda..89ea502 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -115,6 +115,14 @@ New Features
 
   Linux uevent is supported as backend of this device event notification framework.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma.rst` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
                     ` (8 preceding siblings ...)
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 9/9 v2] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
@ 2018-04-20  4:10   ` Nipun Gupta
  2018-04-20 10:34     ` Nipun Gupta
  9 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20  4:10 UTC (permalink / raw)
  To: Shreyansh Jain, thomas, Hemant Agrawal; +Cc: dev

Hi Shreyansh,

I have taken care of all your comments from the v1 series as all were appropriate :)

Also I have rebased on master branch and will rebase CMDIF series over this one.
This lead to addition of patch 4 and some more changes in patch 3 here. Please re-review these.

Thanks,
Nipun

> -----Original Message-----
> From: Nipun Gupta
> Sent: Friday, April 20, 2018 9:34 AM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>; thomas@monjalon.net; Hemant
> Agrawal <hemant.agrawal@nxp.com>
> Cc: dev@dpdk.org; Nipun Gupta <nipun.gupta@nxp.com>
> Subject: [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
> 
> This patch set introduces DPAA2 based QDMA device driver.
> 
> It provide means to initiate a DMA transaction from CPU.
> The initiated DMA is performed without CPU being involved
> in the actual DMA transaction.
> 
> This patch series is rebased on dpdk master branch
> 
> Patches 1-4:
>   Makes necessary changes in the DPAA2 bus
> Patches 5-7:
>   Add the DPAA2 QDMA driver
> Patches 8-9:
>   Update the respective documentation
> 
> Changes in v2:
>   - Rebased over master branch
>   - Pulled in couple of changes which were in CMDIF series
>     - patch 3: some updations, patch 4
>   - handle failues in device init correctly
>   - Updated the logging, added DP logs
>   - Fixed remove_hw_queues_from_list function
> 
> Nipun Gupta (9):
>   bus/fslmc: support MC DPDMAI object
>   bus/fslmc: support scanning and probing of QDMA devices
>   bus/fslmc: add macros required by QDMA for FLE and FD
>   bus/fslmc: fix typecasting in IOVA/virt conversion macros
>   raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
>   raw/dpaa2_qdma: support configuration APIs
>   raw/dpaa2_qdma: support enq and deq operations
>   doc: add DPAA2 QDMA rawdev guide
>   doc: add dpaa2 qdma rawdev to release notes
> 
>  MAINTAINERS                                        |    9 +
>  config/common_base                                 |    1 +
>  config/common_linuxapp                             |    1 +
>  doc/api/doxy-api-index.md                          |    1 +
>  doc/api/doxy-api.conf                              |    1 +
>  doc/guides/index.rst                               |    1 +
>  doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
>  doc/guides/rawdevs/index.rst                       |   14 +
>  doc/guides/rel_notes/release_18_05.rst             |    8 +
>  drivers/bus/fslmc/Makefile                         |    9 +-
>  drivers/bus/fslmc/fslmc_bus.c                      |    2 +
>  drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
>  drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
>  drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
>  drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
>  drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |   12 +-
>  drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
>  drivers/bus/fslmc/rte_fslmc.h                      |    2 +
>  drivers/raw/Makefile                               |    4 +
>  drivers/raw/dpaa2_qdma/Makefile                    |   36 +
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002
> ++++++++++++++++++++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
>  drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
>  .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
>  mk/rte.app.mk                                      |    3 +
>  26 files changed, 2476 insertions(+), 7 deletions(-)
>  create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
>  create mode 100644 doc/guides/rawdevs/index.rst
>  create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
>  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
>  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
>  create mode 100644 drivers/raw/dpaa2_qdma/Makefile
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
>  create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
>  create mode 100644
> drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> 
> --
> 1.9.1

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

* Re: [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-20  4:04   ` [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-20  9:17     ` Hemant Agrawal
  0 siblings, 0 replies; 95+ messages in thread
From: Hemant Agrawal @ 2018-04-20  9:17 UTC (permalink / raw)
  To: Nipun Gupta, shreyansh.jain, thomas, hemant.agrawal; +Cc: dev



On 4/20/2018 9:34 AM, Nipun Gupta wrote:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>

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

* [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (8 preceding siblings ...)
  2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-04-20 10:30 ` Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 1/9 v3] bus/fslmc: support MC DPDMAI object Nipun Gupta
                     ` (9 more replies)
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
  10 siblings, 10 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:30 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patches 1-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patches 8-9:
  Update the respective documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Nipun Gupta (9):
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  bus/fslmc: fix typecasting in IOVA/virt conversion macros
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide
  doc: add dpaa2 qdma rawdev to release notes

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    1 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |   12 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/raw/Makefile                               |    4 +
 drivers/raw/dpaa2_qdma/Makefile                    |   36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 mk/rte.app.mk                                      |    3 +
 26 files changed, 2476 insertions(+), 7 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

-- 
1.9.1

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

* [dpdk-dev] [PATCH 1/9 v3] bus/fslmc: support MC DPDMAI object
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
@ 2018-04-20 10:30   ` Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 2/9 v3] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:30 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 5 files changed, 739 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 2/9 v3] bus/fslmc: support scanning and probing of QDMA devices
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 1/9 v3] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-04-20 10:30   ` Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 3/9 v3] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:30 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index d0b3261..a3898b5 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 675d160..44d4cba 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 3/9 v3] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 1/9 v3] bus/fslmc: support MC DPDMAI object Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 2/9 v3] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-04-20 10:30   ` Nipun Gupta
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 4/9 v3] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:30 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 72aae43..1b67bed 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH 4/9 v3] bus/fslmc: fix typecasting in IOVA/virt conversion macros
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (2 preceding siblings ...)
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 3/9 v3] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-20 10:30   ` Nipun Gupta
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 5/9 v3] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:30 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta, stable

Fixes: df0011c92312 ("bus/fslmc: add physical-virtual address translation helpers")
Cc: stable@dpdk.org

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 1b67bed..507bff7 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -316,8 +316,8 @@ static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr)
 
 #define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) ((mbuf)->buf_addr)
 #define DPAA2_OP_VADDR_TO_IOVA(op) (op)
-#define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr)
-#define DPAA2_IOVA_TO_VADDR(_iova) (_iova)
+#define DPAA2_VADDR_TO_IOVA(_vaddr) ((phys_addr_t)(_vaddr))
+#define DPAA2_IOVA_TO_VADDR(_iova) ((void *)(_iova))
 #define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type)
 
 #endif /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 5/9 v3] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (3 preceding siblings ...)
  2018-04-20 10:30   ` [dpdk-dev] [PATCH 4/9 v3] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
@ 2018-04-20 10:31   ` Nipun Gupta
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 6/9 v3] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:31 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   1 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   4 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 295 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 mk/rte.app.mk                                      |   3 +
 10 files changed, 462 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index f43e3fe..dc226d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -773,6 +773,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index c2b0d91..ed957db 100644
--- a/config/common_base
+++ b/config/common_base
@@ -210,6 +210,7 @@ CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
 #
 CONFIG_RTE_LIBRTE_DPAA2_PMD=n
 CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=n
 
 #
 # Compile burst-oriented Amazon ENA PMD driver
diff --git a/config/common_linuxapp b/config/common_linuxapp
index d0437e5..99fb25a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -37,3 +37,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..b563fc8 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma
+endif
+
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..f81ee08
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9c5b0bc
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,295 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops = {
+};
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..9b9ab1a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+DPDK_18.05 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8bab901..888b12f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -246,6 +246,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH 6/9 v3] raw/dpaa2_qdma: support configuration APIs
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (4 preceding siblings ...)
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 5/9 v3] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-20 10:31   ` Nipun Gupta
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 7/9 v3] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:31 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 7 files changed, 670 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ad8bdcf..18a7ed4 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index f81ee08..6711df3 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9c5b0bc..2325a8d 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops = {
 };
 
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..d27fd49
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 9b9ab1a..0a0d3c5 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 DPDK_18.05 {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH 7/9 v3] raw/dpaa2_qdma: support enq and deq operations
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (5 preceding siblings ...)
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 6/9 v3] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-04-20 10:31   ` Nipun Gupta
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 8/9 v3] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:31 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 332 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 427 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 2325a8d..6e3bf49 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,338 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd = {};
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index d27fd49..5a0ee4e 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job *
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 0a0d3c5..59dd27c 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ DPDK_18.05 {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 8/9 v3] doc: add DPAA2 QDMA rawdev guide
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (6 preceding siblings ...)
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 7/9 v3] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-04-20 10:31   ` Nipun Gupta
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
  2018-04-23  0:05   ` [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver Thomas Monjalon
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:31 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                       |   1 +
 doc/guides/index.rst              |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst | 140 ++++++++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst      |  14 ++++
 4 files changed, 156 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index dc226d8..d6f9a4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -779,6 +779,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..85e4d2d
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP SDK **2.0+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
-- 
1.9.1

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

* [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (7 preceding siblings ...)
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 8/9 v3] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-04-20 10:31   ` Nipun Gupta
  2018-04-23  0:03     ` Thomas Monjalon
  2018-04-23  0:05   ` [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver Thomas Monjalon
  9 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:31 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/guides/rel_notes/release_18_05.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 290fa09..ebfd57f 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -115,6 +115,14 @@ New Features
 
   Linux uevent is supported as backend of this device event notification framework.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma.rst` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
  2018-04-20  4:10   ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-04-20 10:34     ` Nipun Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-20 10:34 UTC (permalink / raw)
  To: Shreyansh Jain, thomas, Hemant Agrawal; +Cc: dev

There is a compilation issue due to a recent change on master branch
http://dpdk.org/browse/dpdk/commit/?id=3ef648aa4854f53b5ad3f148dc021852157a0246

I am sending a v3 fixing the compilation issue.

Regards,
Nipun

> -----Original Message-----
> From: Nipun Gupta
> Sent: Friday, April 20, 2018 9:40 AM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>; thomas@monjalon.net; Hemant
> Agrawal <hemant.agrawal@nxp.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
> 
> Hi Shreyansh,
> 
> I have taken care of all your comments from the v1 series as all were
> appropriate :)
> 
> Also I have rebased on master branch and will rebase CMDIF series over this one.
> This lead to addition of patch 4 and some more changes in patch 3 here. Please
> re-review these.
> 
> Thanks,
> Nipun
> 
> > -----Original Message-----
> > From: Nipun Gupta
> > Sent: Friday, April 20, 2018 9:34 AM
> > To: Shreyansh Jain <shreyansh.jain@nxp.com>; thomas@monjalon.net;
> Hemant
> > Agrawal <hemant.agrawal@nxp.com>
> > Cc: dev@dpdk.org; Nipun Gupta <nipun.gupta@nxp.com>
> > Subject: [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver
> >
> > This patch set introduces DPAA2 based QDMA device driver.
> >
> > It provide means to initiate a DMA transaction from CPU.
> > The initiated DMA is performed without CPU being involved
> > in the actual DMA transaction.
> >
> > This patch series is rebased on dpdk master branch
> >
> > Patches 1-4:
> >   Makes necessary changes in the DPAA2 bus
> > Patches 5-7:
> >   Add the DPAA2 QDMA driver
> > Patches 8-9:
> >   Update the respective documentation
> >
> > Changes in v2:
> >   - Rebased over master branch
> >   - Pulled in couple of changes which were in CMDIF series
> >     - patch 3: some updations, patch 4
> >   - handle failues in device init correctly
> >   - Updated the logging, added DP logs
> >   - Fixed remove_hw_queues_from_list function
> >
> > Nipun Gupta (9):
> >   bus/fslmc: support MC DPDMAI object
> >   bus/fslmc: support scanning and probing of QDMA devices
> >   bus/fslmc: add macros required by QDMA for FLE and FD
> >   bus/fslmc: fix typecasting in IOVA/virt conversion macros
> >   raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
> >   raw/dpaa2_qdma: support configuration APIs
> >   raw/dpaa2_qdma: support enq and deq operations
> >   doc: add DPAA2 QDMA rawdev guide
> >   doc: add dpaa2 qdma rawdev to release notes
> >
> >  MAINTAINERS                                        |    9 +
> >  config/common_base                                 |    1 +
> >  config/common_linuxapp                             |    1 +
> >  doc/api/doxy-api-index.md                          |    1 +
> >  doc/api/doxy-api.conf                              |    1 +
> >  doc/guides/index.rst                               |    1 +
> >  doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
> >  doc/guides/rawdevs/index.rst                       |   14 +
> >  doc/guides/rel_notes/release_18_05.rst             |    8 +
> >  drivers/bus/fslmc/Makefile                         |    9 +-
> >  drivers/bus/fslmc/fslmc_bus.c                      |    2 +
> >  drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
> >  drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
> >  drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
> >  drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
> >  drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |   12 +-
> >  drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
> >  drivers/bus/fslmc/rte_fslmc.h                      |    2 +
> >  drivers/raw/Makefile                               |    4 +
> >  drivers/raw/dpaa2_qdma/Makefile                    |   36 +
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002
> > ++++++++++++++++++++
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
> >  drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
> >  .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
> >  mk/rte.app.mk                                      |    3 +
> >  26 files changed, 2476 insertions(+), 7 deletions(-)
> >  create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
> >  create mode 100644 doc/guides/rawdevs/index.rst
> >  create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
> >  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
> >  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
> >  create mode 100644 drivers/raw/dpaa2_qdma/Makefile
> >  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
> >  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
> >  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
> >  create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
> >  create mode 100644
> > drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> >
> > --
> > 1.9.1

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

* Re: [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
@ 2018-04-23  0:03     ` Thomas Monjalon
  2018-04-23  8:45       ` Nipun Gupta
  0 siblings, 1 reply; 95+ messages in thread
From: Thomas Monjalon @ 2018-04-23  0:03 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev, shreyansh.jain, hemant.agrawal

20/04/2018 12:31, Nipun Gupta:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>  doc/guides/rel_notes/release_18_05.rst | 8 ++++++++
>  1 file changed, 8 insertions(+)

Please merge this patch in the previous one.

> +* **Added DPAA2 QDMA Driver (in rawdev).**
> +
> +  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
> +  to initiate a DMA transaction from CPU. The initiated DMA is performed
> +  without CPU being involved in the actual DMA transaction.
> +
> +  See the :doc:`../rawdevs/dpaa2_qdma.rst` guide for more details.

I think you must remove the .rst extension.

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

* Re: [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
                     ` (8 preceding siblings ...)
  2018-04-20 10:31   ` [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
@ 2018-04-23  0:05   ` Thomas Monjalon
  2018-04-23  8:46     ` Nipun Gupta
  9 siblings, 1 reply; 95+ messages in thread
From: Thomas Monjalon @ 2018-04-23  0:05 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev, shreyansh.jain, hemant.agrawal

20/04/2018 12:30, Nipun Gupta:
> This patch set introduces DPAA2 based QDMA device driver.
> 
> It provide means to initiate a DMA transaction from CPU.
> The initiated DMA is performed without CPU being involved
> in the actual DMA transaction.

3 comments:

1/ Please compile this driver with meson.

2/ I think you should declare the new API functions as experimental.

3/ This series won't be in RC1, but is candidate for RC2. Is it OK?

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

* Re: [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes
  2018-04-23  0:03     ` Thomas Monjalon
@ 2018-04-23  8:45       ` Nipun Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-23  8:45 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, Hemant Agrawal



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, April 23, 2018 5:34 AM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release
> notes
> 
> 20/04/2018 12:31, Nipun Gupta:
> > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > ---
> >  doc/guides/rel_notes/release_18_05.rst | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> 
> Please merge this patch in the previous one.

Sure.. I will do that :)

> 
> > +* **Added DPAA2 QDMA Driver (in rawdev).**
> > +
> > +  The DPAA2 QDMA is an implementation of the rawdev API, that provide
> means
> > +  to initiate a DMA transaction from CPU. The initiated DMA is performed
> > +  without CPU being involved in the actual DMA transaction.
> > +
> > +  See the :doc:`../rawdevs/dpaa2_qdma.rst` guide for more details.
> 
> I think you must remove the .rst extension.

Okay.

Thanks,
Nipun

> 
> 
> 

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

* Re: [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver
  2018-04-23  0:05   ` [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver Thomas Monjalon
@ 2018-04-23  8:46     ` Nipun Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-23  8:46 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, Hemant Agrawal



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, April 23, 2018 5:36 AM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver
> 
> 20/04/2018 12:30, Nipun Gupta:
> > This patch set introduces DPAA2 based QDMA device driver.
> >
> > It provide means to initiate a DMA transaction from CPU.
> > The initiated DMA is performed without CPU being involved
> > in the actual DMA transaction.
> 
> 3 comments:
> 
> 1/ Please compile this driver with meson.

Okay..

> 
> 2/ I think you should declare the new API functions as experimental.

Agree. Ill add it.

> 
> 3/ This series won't be in RC1, but is candidate for RC2. Is it OK?

Sure. No issues. Thanks.

Nipun

> 

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

* [dpdk-dev] [PATCH 0/8 v4] Introduce DPAA2 QDMA raw driver
  2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                   ` (9 preceding siblings ...)
  2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
@ 2018-04-24 11:49 ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 1/8 v4] raw: support meson build Nipun Gupta
                     ` (8 more replies)
  10 siblings, 9 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patch 1:
  Support meson build in raw
Patches 2-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patch 8:
  Update the documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Changes in v4:
  - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
  - Merged the two separate doc patches (patch 8)

Nipun Gupta (8):
  raw: support meson build
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    5 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/meson.build                      |    1 +
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/meson.build                                |    3 +-
 drivers/raw/Makefile                               |    3 +
 drivers/raw/dpaa2_qdma/Makefile                    |   36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/meson.build                 |    9 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 drivers/raw/meson.build                            |    7 +
 drivers/raw/skeleton_rawdev/meson.build            |    8 +
 mk/rte.app.mk                                      |    3 +
 31 files changed, 2504 insertions(+), 6 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

-- 
1.9.1

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

* [dpdk-dev] [PATCH 1/8 v4] raw: support meson build
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-26  6:58     ` Shreyansh Jain
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 2/8 v4] bus/fslmc: support MC DPDMAI object Nipun Gupta
                     ` (7 subsequent siblings)
  8 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/meson.build                     | 3 ++-
 drivers/raw/meson.build                 | 7 +++++++
 drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

diff --git a/drivers/meson.build b/drivers/meson.build
index b146f09..f879cb6 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -7,7 +7,8 @@ driver_classes = ['common',
 	       'mempool', # depends on common and bus.
 	       'net',     # depends on common, bus and mempool.
 	       'crypto',  # depends on common, bus and mempool (net in future).
-	       'event']   # depends on common, bus, mempool and net.
+	       'event',   # depends on common, bus, mempool and net.
+	       'raw']     # depends on common, bus, mempool, net and event.
 
 foreach class:driver_classes
 	drivers = []
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
new file mode 100644
index 0000000..24c82ff
--- /dev/null
+++ b/drivers/raw/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+drivers = ['skeleton_rawdev']
+std_deps = ['rawdev']
+config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
+driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/skeleton_rawdev/meson.build b/drivers/raw/skeleton_rawdev/meson.build
new file mode 100644
index 0000000..7cb2d3f
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
+sources = files('skeleton_rawdev.c',
+               'skeleton_rawdev_test.c')
+
+allow_experimental_apis = true
-- 
1.9.1

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

* [dpdk-dev] [PATCH 2/8 v4] bus/fslmc: support MC DPDMAI object
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 1/8 v4] raw: support meson build Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 3/8 v4] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/meson.build               |   1 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 6 files changed, 740 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 890d6c0..22a56a6 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -11,6 +11,7 @@ sources = files('fslmc_bus.c',
 		'mc/dpbp.c',
 		'mc/dpci.c',
 		'mc/dpcon.c',
+		'mc/dpdmai.c',
 		'mc/dpio.c',
 		'mc/dpmng.c',
 		'mc/mc_sys.c',
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 3/8 v4] bus/fslmc: support scanning and probing of QDMA devices
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 1/8 v4] raw: support meson build Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 2/8 v4] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 4/8 v4] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index d0b3261..a3898b5 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 675d160..44d4cba 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH 4/8 v4] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (2 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 3/8 v4] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index c76393d..8fd4ef9 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (3 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 4/8 v4] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-30 12:34     ` Thomas Monjalon
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 6/8 v4] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   5 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   9 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 474 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 645bd52..d7e9aa5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -784,6 +784,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 7e45412..f69e867 100644
--- a/config/common_base
+++ b/config/common_base
@@ -617,6 +617,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index d0437e5..f752a0f 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -37,3 +37,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..3b5a45a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..7b53370
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'bus_fslmc', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_qdma.h')
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a145791..ff90dec 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -247,6 +247,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH 6/8 v4] raw/dpaa2_qdma: support configuration APIs
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (4 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 7/8 v4] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 7 files changed, 670 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ad8bdcf..18a7ed4 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index 3b5a45a..264eca8 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9288350..b38a282 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int __rte_experimental
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int __rte_experimental
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void __rte_experimental
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops;
 
 static int
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..29a1e4b
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void __rte_experimental
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void __rte_experimental
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 33d2379..7335c35 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 EXPERIMENTAL {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH 7/8 v4] raw/dpaa2_qdma: support enq and deq operations
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (5 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 6/8 v4] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 8/8 v4] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 333 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 428 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b38a282..1d15c30 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,339 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd;
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	memset(&fd, 0, sizeof(struct qbman_fd));
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void __rte_experimental
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index 29a1e4b..17fffcb 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 7335c35..fe42a22 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ EXPERIMENTAL {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH 8/8 v4] doc: add DPAA2 QDMA rawdev guide
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (6 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 7/8 v4] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-04-24 11:49   ` Nipun Gupta
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-04-24 11:49 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/index.rst                   |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst      | 140 +++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst           |  14 ++++
 doc/guides/rel_notes/release_18_05.rst |   8 ++
 5 files changed, 164 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index d7e9aa5..b8c1541 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -790,6 +790,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..b9bc4ec
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP LSDK **17.12+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 5276882..cb6d220 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -134,6 +134,14 @@ New Features
 
   Linux uevent is supported as backend of this device event notification framework.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH 1/8 v4] raw: support meson build
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 1/8 v4] raw: support meson build Nipun Gupta
@ 2018-04-26  6:58     ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-04-26  6:58 UTC (permalink / raw)
  To: Nipun Gupta, thomas; +Cc: hemant.agrawal, dev

On Tuesday 24 April 2018 05:19 PM, Nipun Gupta wrote:
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>   drivers/meson.build                     | 3 ++-
>   drivers/raw/meson.build                 | 7 +++++++
>   drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
>   3 files changed, 17 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/raw/meson.build
>   create mode 100644 drivers/raw/skeleton_rawdev/meson.build
> 

Compilation verified for Clang-5, i686, arm64 and x86_64 (gcc 7.2).

For the series:

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

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

* Re: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-04-30 12:34     ` Thomas Monjalon
  2018-05-01  6:14       ` Nipun Gupta
  0 siblings, 1 reply; 95+ messages in thread
From: Thomas Monjalon @ 2018-04-30 12:34 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev, shreyansh.jain, hemant.agrawal

24/04/2018 13:49, Nipun Gupta:
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
[...]
> +install_headers('rte_pmd_dpaa2_qdma.h')

I think you need to rename the exported header file with rte_pmd_ prefix.

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

* Re: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-04-30 12:34     ` Thomas Monjalon
@ 2018-05-01  6:14       ` Nipun Gupta
  2018-05-01  6:21         ` Nipun Gupta
  0 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  6:14 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, Hemant Agrawal



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, April 30, 2018 6:05 PM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant
> Agrawal <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the
> DPAA2 QDMA driver
> 
> 24/04/2018 13:49, Nipun Gupta:
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294
> +++++++++++++++++++++
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
> >  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
> [...]
> > +install_headers('rte_pmd_dpaa2_qdma.h')
> 
> I think you need to rename the exported header file with rte_pmd_ prefix.

Sorry, I did not get it. Filename is already with rte_pmd_ prefix.

Thanks,
Nipun

> 

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

* Re: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-01  6:14       ` Nipun Gupta
@ 2018-05-01  6:21         ` Nipun Gupta
  0 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  6:21 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, Hemant Agrawal



> -----Original Message-----
> From: Nipun Gupta
> Sent: Tuesday, May 1, 2018 11:44 AM
> To: 'Thomas Monjalon' <thomas@monjalon.net>
> Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant
> Agrawal <hemant.agrawal@nxp.com>
> Subject: RE: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the
> DPAA2 QDMA driver
> 
> 
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > Sent: Monday, April 30, 2018 6:05 PM
> > To: Nipun Gupta <nipun.gupta@nxp.com>
> > Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>; Hemant
> > Agrawal <hemant.agrawal@nxp.com>
> > Subject: Re: [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the
> > DPAA2 QDMA driver
> >
> > 24/04/2018 13:49, Nipun Gupta:
> > >  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294
> > +++++++++++++++++++++
> > >  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
> > >  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
> > [...]
> > > +install_headers('rte_pmd_dpaa2_qdma.h')
> >
> > I think you need to rename the exported header file with rte_pmd_ prefix.

Got it. This should be in the next patch where 'rte_pmd_dpaa2_qdma.h' file has been introduced.
I will fix it and respin a version.

> 
> Sorry, I did not get it. Filename is already with rte_pmd_ prefix.
> 
> Thanks,
> Nipun
> 
> >

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

* [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver
  2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
                     ` (7 preceding siblings ...)
  2018-04-24 11:49   ` [dpdk-dev] [PATCH 8/8 v4] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-01  9:58   ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 1/8] raw: support meson build Nipun Gupta
                       ` (8 more replies)
  8 siblings, 9 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patch 1:
  Support meson build in raw
Patches 2-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patch 8:
  Update the documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Changes in v4:
  - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
  - Merged the two separate doc patches (patch 8)

Changes in v5:
  - install user header file (rte_pmd_dpaa2_qdma.h) in case of
    meson build where it is introduced (patch 6). Previously
    it was added in patch 5.

Nipun Gupta (8):
  raw: support meson build
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    5 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/meson.build                      |    1 +
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/meson.build                                |    3 +-
 drivers/raw/Makefile                               |    3 +
 drivers/raw/dpaa2_qdma/Makefile                    |   36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/meson.build                 |    9 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 drivers/raw/meson.build                            |    7 +
 drivers/raw/skeleton_rawdev/meson.build            |    8 +
 mk/rte.app.mk                                      |    3 +
 31 files changed, 2504 insertions(+), 6 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 1/8] raw: support meson build
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
                       ` (7 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/meson.build                     | 3 ++-
 drivers/raw/meson.build                 | 7 +++++++
 drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

diff --git a/drivers/meson.build b/drivers/meson.build
index b146f09..f879cb6 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -7,7 +7,8 @@ driver_classes = ['common',
 	       'mempool', # depends on common and bus.
 	       'net',     # depends on common, bus and mempool.
 	       'crypto',  # depends on common, bus and mempool (net in future).
-	       'event']   # depends on common, bus, mempool and net.
+	       'event',   # depends on common, bus, mempool and net.
+	       'raw']     # depends on common, bus, mempool, net and event.
 
 foreach class:driver_classes
 	drivers = []
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
new file mode 100644
index 0000000..24c82ff
--- /dev/null
+++ b/drivers/raw/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+drivers = ['skeleton_rawdev']
+std_deps = ['rawdev']
+config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
+driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/skeleton_rawdev/meson.build b/drivers/raw/skeleton_rawdev/meson.build
new file mode 100644
index 0000000..7cb2d3f
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
+sources = files('skeleton_rawdev.c',
+               'skeleton_rawdev_test.c')
+
+allow_experimental_apis = true
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 2/8] bus/fslmc: support MC DPDMAI object
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 1/8] raw: support meson build Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                       ` (6 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/meson.build               |   1 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 6 files changed, 740 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 890d6c0..22a56a6 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -11,6 +11,7 @@ sources = files('fslmc_bus.c',
 		'mc/dpbp.c',
 		'mc/dpci.c',
 		'mc/dpcon.c',
+		'mc/dpdmai.c',
 		'mc/dpio.c',
 		'mc/dpmng.c',
 		'mc/mc_sys.c',
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 3/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 1/8] raw: support meson build Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                       ` (5 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 943c01b..fde5f19 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 749d92d..3800c26 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 4/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (2 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                       ` (4 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e081afb..09ea603 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (3 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                       ` (3 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   5 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   7 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 472 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ce06e93..5ca021d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -805,6 +805,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 03a8688..9b48bcb 100644
--- a/config/common_base
+++ b/config/common_base
@@ -618,6 +618,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 14e56cb..21b3fe3 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..3b5a45a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..cf14c01
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'bus_fslmc', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a60..26a6b0c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -251,6 +251,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (4 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                       ` (2 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   2 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 8 files changed, 672 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 5686cbb..88bee03 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index 3b5a45a..264eca8 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9288350..b38a282 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int __rte_experimental
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int __rte_experimental
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void __rte_experimental
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops;
 
 static int
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
index cf14c01..7b53370 100644
--- a/drivers/raw/dpaa2_qdma/meson.build
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -5,3 +5,5 @@ deps += ['rawdev', 'bus_fslmc', 'ring']
 sources = files('dpaa2_qdma.c')
 
 allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_qdma.h')
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..29a1e4b
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void __rte_experimental
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void __rte_experimental
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 33d2379..7335c35 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 EXPERIMENTAL {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 7/8] raw/dpaa2_qdma: support enq and deq operations
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (5 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 333 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 428 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b38a282..1d15c30 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,339 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd;
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	memset(&fd, 0, sizeof(struct qbman_fd));
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void __rte_experimental
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index 29a1e4b..17fffcb 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 7335c35..fe42a22 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ EXPERIMENTAL {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v5 8/8] doc: add DPAA2 QDMA rawdev guide
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (6 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-05-01  9:58     ` Nipun Gupta
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-01  9:58 UTC (permalink / raw)
  To: shreyansh.jain, thomas, hemant.agrawal; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/index.rst                   |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst      | 140 +++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst           |  14 ++++
 doc/guides/rel_notes/release_18_05.rst |   8 ++
 5 files changed, 164 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 5ca021d..3fc4a2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -811,6 +811,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..b9bc4ec
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP LSDK **17.12+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..22fa74d 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -164,6 +164,14 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver
  2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                       ` (7 preceding siblings ...)
  2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-02 17:09     ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 1/8] raw: support meson build Nipun Gupta
                         ` (9 more replies)
  8 siblings, 10 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patch 1:
  Support meson build in raw
Patches 2-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patch 8:
  Update the documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Changes in v4:
  - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
  - Merged the two separate doc patches (patch 8)

Changes in v5:
  - install user header file (rte_pmd_dpaa2_qdma.h) in case of
    meson build where it is introduced (patch 6). Previously
    it was added in patch 5.

Changes in v6:
  - Fix meson shared build

Nipun Gupta (8):
  raw: support meson build
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    5 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/meson.build                      |    1 +
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/meson.build                                |    3 +-
 drivers/raw/Makefile                               |    3 +
 drivers/raw/dpaa2_qdma/Makefile                    |   36 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/meson.build                 |    9 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 drivers/raw/meson.build                            |    7 +
 drivers/raw/skeleton_rawdev/meson.build            |    8 +
 mk/rte.app.mk                                      |    3 +
 31 files changed, 2504 insertions(+), 6 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 1/8] raw: support meson build
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
                         ` (8 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/meson.build                     | 3 ++-
 drivers/raw/meson.build                 | 7 +++++++
 drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

diff --git a/drivers/meson.build b/drivers/meson.build
index b146f09..f879cb6 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -7,7 +7,8 @@ driver_classes = ['common',
 	       'mempool', # depends on common and bus.
 	       'net',     # depends on common, bus and mempool.
 	       'crypto',  # depends on common, bus and mempool (net in future).
-	       'event']   # depends on common, bus, mempool and net.
+	       'event',   # depends on common, bus, mempool and net.
+	       'raw']     # depends on common, bus, mempool, net and event.
 
 foreach class:driver_classes
 	drivers = []
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
new file mode 100644
index 0000000..24c82ff
--- /dev/null
+++ b/drivers/raw/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+drivers = ['skeleton_rawdev']
+std_deps = ['rawdev']
+config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
+driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/skeleton_rawdev/meson.build b/drivers/raw/skeleton_rawdev/meson.build
new file mode 100644
index 0000000..7cb2d3f
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
+sources = files('skeleton_rawdev.c',
+               'skeleton_rawdev_test.c')
+
+allow_experimental_apis = true
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 2/8] bus/fslmc: support MC DPDMAI object
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 1/8] raw: support meson build Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                         ` (7 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/meson.build               |   1 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 6 files changed, 740 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 890d6c0..22a56a6 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -11,6 +11,7 @@ sources = files('fslmc_bus.c',
 		'mc/dpbp.c',
 		'mc/dpci.c',
 		'mc/dpcon.c',
+		'mc/dpdmai.c',
 		'mc/dpio.c',
 		'mc/dpmng.c',
 		'mc/mc_sys.c',
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 3/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 1/8] raw: support meson build Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                         ` (6 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 943c01b..fde5f19 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 749d92d..3800c26 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 4/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (2 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                         ` (5 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e081afb..09ea603 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (3 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-03 14:07         ` Shreyansh Jain
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                         ` (4 subsequent siblings)
  9 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   5 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   7 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 472 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ce06e93..5ca021d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -805,6 +805,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 03a8688..9b48bcb 100644
--- a/config/common_base
+++ b/config/common_base
@@ -618,6 +618,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 14e56cb..21b3fe3 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..3b5a45a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..cf14c01
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'mempool_dpaa2', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a60..26a6b0c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -251,6 +251,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (4 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                         ` (3 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   2 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 8 files changed, 672 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 5686cbb..88bee03 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index 3b5a45a..264eca8 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9288350..b38a282 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int __rte_experimental
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int __rte_experimental
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void __rte_experimental
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops;
 
 static int
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
index cf14c01..7b53370 100644
--- a/drivers/raw/dpaa2_qdma/meson.build
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -5,3 +5,5 @@ deps += ['rawdev', 'bus_fslmc', 'ring']
 sources = files('dpaa2_qdma.c')
 
 allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_qdma.h')
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..29a1e4b
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void __rte_experimental
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void __rte_experimental
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 33d2379..7335c35 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 EXPERIMENTAL {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 7/8] raw/dpaa2_qdma: support enq and deq operations
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (5 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
                         ` (2 subsequent siblings)
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 333 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 428 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b38a282..1d15c30 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,339 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd;
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	memset(&fd, 0, sizeof(struct qbman_fd));
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void __rte_experimental
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index 29a1e4b..17fffcb 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 7335c35..fe42a22 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ EXPERIMENTAL {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v6 8/8] doc: add DPAA2 QDMA rawdev guide
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (6 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-05-02 17:09       ` Nipun Gupta
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
  9 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-02 17:09 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/index.rst                   |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst      | 140 +++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst           |  14 ++++
 doc/guides/rel_notes/release_18_05.rst |   8 ++
 5 files changed, 164 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 5ca021d..3fc4a2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -811,6 +811,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..b9bc4ec
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP LSDK **17.12+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..22fa74d 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -164,6 +164,14 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-05-03 14:07         ` Shreyansh Jain
  0 siblings, 0 replies; 95+ messages in thread
From: Shreyansh Jain @ 2018-05-03 14:07 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: thomas, hemant.agrawal, dev

On Wednesday 02 May 2018 10:39 PM, Nipun Gupta wrote:
> DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
> the user (app) to perform data DMA without involving CPU in
> the DMA process
> 
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
>   MAINTAINERS                                        |   8 +
>   config/common_base                                 |   5 +
>   config/common_linuxapp                             |   1 +
>   drivers/raw/Makefile                               |   3 +
>   drivers/raw/dpaa2_qdma/Makefile                    |  34 +++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
>   drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
>   drivers/raw/dpaa2_qdma/meson.build                 |   7 +
>   .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
>   drivers/raw/meson.build                            |   2 +-
>   mk/rte.app.mk                                      |   3 +
>   12 files changed, 472 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/raw/dpaa2_qdma/Makefile
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
>   create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
>   create mode 100644 drivers/raw/dpaa2_qdma/meson.build
>   create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> 

[...]

> diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
> new file mode 100644
> index 0000000..3b5a45a
> --- /dev/null
> +++ b/drivers/raw/dpaa2_qdma/Makefile
> @@ -0,0 +1,34 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright 2018 NXP
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_pmd_dpaa2_qdma.a
> +
> +CFLAGS += -DALLOW_EXPERIMENTAL_API
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
> +CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
> +CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
> +
> +LDLIBS += -lrte_bus_fslmc
> +LDLIBS += -lrte_eal
> +LDLIBS += -lrte_mempool
> +LDLIBS += -lrte_rawdev
> +LDLIBS += -lrte_ring

Shared lib (x86_64 build) fails with dependency on rte_mempool_dpaa2.
Using:

LDLIBS += -lrte_mempool_dpaa2

Succeeds.

> +
> +EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
> +
> +LIBABIVER := 1
> +
> +#
> +# all source are stored in SRCS-y
> +#
> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
> +
> +include $(RTE_SDK)/mk/rte.lib.mk

[...]

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

* [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (7 preceding siblings ...)
  2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-03 15:51       ` Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 1/8] raw: support meson build Nipun Gupta
                           ` (8 more replies)
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
  9 siblings, 9 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patch 1:
  Support meson build in raw
Patches 2-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patch 8:
  Update the documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Changes in v4:
  - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
  - Merged the two separate doc patches (patch 8)

Changes in v5:
  - install user header file (rte_pmd_dpaa2_qdma.h) in case of
    meson build where it is introduced (patch 6). Previously
    it was added in patch 5.

Changes in v6:
  - Fix meson shared build

Changes in v7:
  - Fix x86 shared build

Nipun Gupta (8):
  raw: support meson build
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    7 +-
 config/common_linuxapp                             |   13 +-
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/meson.build                      |    1 +
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/meson.build                                |    3 +-
 drivers/raw/Makefile                               |    3 +
 drivers/raw/dpaa2_qdma/Makefile                    |   37 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/meson.build                 |    9 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 drivers/raw/meson.build                            |    7 +
 drivers/raw/skeleton_rawdev/meson.build            |    8 +
 mk/rte.app.mk                                      |    3 +
 31 files changed, 2512 insertions(+), 13 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 1/8] raw: support meson build
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-05-03 15:51         ` Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
                           ` (7 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/meson.build                     | 3 ++-
 drivers/raw/meson.build                 | 7 +++++++
 drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

diff --git a/drivers/meson.build b/drivers/meson.build
index b146f09..f879cb6 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -7,7 +7,8 @@ driver_classes = ['common',
 	       'mempool', # depends on common and bus.
 	       'net',     # depends on common, bus and mempool.
 	       'crypto',  # depends on common, bus and mempool (net in future).
-	       'event']   # depends on common, bus, mempool and net.
+	       'event',   # depends on common, bus, mempool and net.
+	       'raw']     # depends on common, bus, mempool, net and event.
 
 foreach class:driver_classes
 	drivers = []
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
new file mode 100644
index 0000000..24c82ff
--- /dev/null
+++ b/drivers/raw/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+drivers = ['skeleton_rawdev']
+std_deps = ['rawdev']
+config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
+driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/skeleton_rawdev/meson.build b/drivers/raw/skeleton_rawdev/meson.build
new file mode 100644
index 0000000..7cb2d3f
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
+sources = files('skeleton_rawdev.c',
+               'skeleton_rawdev_test.c')
+
+allow_experimental_apis = true
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 2/8] bus/fslmc: support MC DPDMAI object
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 1/8] raw: support meson build Nipun Gupta
@ 2018-05-03 15:51         ` Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                           ` (6 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/meson.build               |   1 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 6 files changed, 740 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 890d6c0..22a56a6 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -11,6 +11,7 @@ sources = files('fslmc_bus.c',
 		'mc/dpbp.c',
 		'mc/dpci.c',
 		'mc/dpcon.c',
+		'mc/dpdmai.c',
 		'mc/dpio.c',
 		'mc/dpmng.c',
 		'mc/mc_sys.c',
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 3/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 1/8] raw: support meson build Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-05-03 15:51         ` Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                           ` (5 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 943c01b..fde5f19 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 749d92d..3800c26 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (2 preceding siblings ...)
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-05-03 15:51         ` Nipun Gupta
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                           ` (4 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e081afb..09ea603 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (3 preceding siblings ...)
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-05-03 15:51         ` Nipun Gupta
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                           ` (3 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   7 +-
 config/common_linuxapp                             |  13 +-
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  35 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   7 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 480 insertions(+), 8 deletions(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ce06e93..5ca021d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -805,6 +805,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 03a8688..b6a649f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -38,7 +38,7 @@ CONFIG_RTE_ARCH_STRICT_ALIGN=n
 #
 # Compile to share library
 #
-CONFIG_RTE_BUILD_SHARED_LIB=n
+CONFIG_RTE_BUILD_SHARED_LIB=y
 
 #
 # Use newest code breaking previous ABI
@@ -618,6 +618,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 14e56cb..8ee495b 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -6,14 +6,14 @@
 CONFIG_RTE_EXEC_ENV="linuxapp"
 CONFIG_RTE_EXEC_ENV_LINUXAPP=y
 
-CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
-CONFIG_RTE_EAL_IGB_UIO=y
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
+CONFIG_RTE_EAL_IGB_UIO=n
 CONFIG_RTE_EAL_VFIO=y
-CONFIG_RTE_KNI_KMOD=y
-CONFIG_RTE_LIBRTE_KNI=y
-CONFIG_RTE_LIBRTE_PMD_KNI=y
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_PMD_KNI=n
 CONFIG_RTE_LIBRTE_VHOST=y
-CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_IFCVF_VDPA_PMD=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..68c785a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_mempool_dpaa2
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..b747500
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'mempool_dpaa2', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a60..26a6b0c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -251,6 +251,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 6/8] raw/dpaa2_qdma: support configuration APIs
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (4 preceding siblings ...)
  2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-05-03 15:52         ` Nipun Gupta
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                           ` (2 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:52 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   2 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 8 files changed, 672 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 5686cbb..88bee03 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index 68c785a..d88809e 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -32,4 +32,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9288350..b38a282 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int __rte_experimental
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int __rte_experimental
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void __rte_experimental
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops;
 
 static int
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
index b747500..a2eb1d2 100644
--- a/drivers/raw/dpaa2_qdma/meson.build
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -5,3 +5,5 @@ deps += ['rawdev', 'mempool_dpaa2', 'ring']
 sources = files('dpaa2_qdma.c')
 
 allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_qdma.h')
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..29a1e4b
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void __rte_experimental
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void __rte_experimental
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 33d2379..7335c35 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 EXPERIMENTAL {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 7/8] raw/dpaa2_qdma: support enq and deq operations
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (5 preceding siblings ...)
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-05-03 15:52         ` Nipun Gupta
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
  2018-05-03 15:58         ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:52 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 333 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 428 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b38a282..1d15c30 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,339 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd;
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	memset(&fd, 0, sizeof(struct qbman_fd));
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void __rte_experimental
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index 29a1e4b..17fffcb 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 7335c35..fe42a22 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ EXPERIMENTAL {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH v7 8/8] doc: add DPAA2 QDMA rawdev guide
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (6 preceding siblings ...)
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-05-03 15:52         ` Nipun Gupta
  2018-05-03 15:58         ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:52 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/index.rst                   |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst      | 140 +++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst           |  14 ++++
 doc/guides/rel_notes/release_18_05.rst |   8 ++
 5 files changed, 164 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 5ca021d..3fc4a2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -811,6 +811,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..b9bc4ec
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP LSDK **17.12+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..22fa74d 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -164,6 +164,14 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                           ` (7 preceding siblings ...)
  2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-03 15:58         ` Nipun Gupta
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 15:58 UTC (permalink / raw)
  To: thomas, Hemant Agrawal, Shreyansh Jain; +Cc: dev

Please ignore this series.

It has some issues. I will resend.

Thanks,
Nipun

> -----Original Message-----
> From: Nipun Gupta
> Sent: Thursday, May 3, 2018 9:22 PM
> To: thomas@monjalon.net; Hemant Agrawal <hemant.agrawal@nxp.com>;
> Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; Nipun Gupta <nipun.gupta@nxp.com>
> Subject: [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver
> 
> This patch set introduces DPAA2 based QDMA device driver.
> 
> It provide means to initiate a DMA transaction from CPU.
> The initiated DMA is performed without CPU being involved
> in the actual DMA transaction.
> 
> This patch series is rebased on dpdk master branch
> 
> Patch 1:
>   Support meson build in raw
> Patches 2-4:
>   Makes necessary changes in the DPAA2 bus
> Patches 5-7:
>   Add the DPAA2 QDMA driver
> Patch 8:
>   Update the documentation
> 
> Changes in v2:
>   - Rebased over master branch
>   - Pulled in couple of changes which were in CMDIF series
>     - patch 3: some updations, patch 4
>   - handle failues in device init correctly
>   - Updated the logging, added DP logs
>   - Fixed remove_hw_queues_from_list function
> 
> Changes in v3:
>   - Fix compilation issue introduced due to a very recent change
>     of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
>     was used.
> 
> Changes in v4:
>   - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
>   - Merged the two separate doc patches (patch 8)
> 
> Changes in v5:
>   - install user header file (rte_pmd_dpaa2_qdma.h) in case of
>     meson build where it is introduced (patch 6). Previously
>     it was added in patch 5.
> 
> Changes in v6:
>   - Fix meson shared build
> 
> Changes in v7:
>   - Fix x86 shared build
> 
> Nipun Gupta (8):
>   raw: support meson build
>   bus/fslmc: support MC DPDMAI object
>   bus/fslmc: support scanning and probing of QDMA devices
>   bus/fslmc: add macros required by QDMA for FLE and FD
>   raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
>   raw/dpaa2_qdma: support configuration APIs
>   raw/dpaa2_qdma: support enq and deq operations
>   doc: add DPAA2 QDMA rawdev guide
> 
>  MAINTAINERS                                        |    9 +
>  config/common_base                                 |    7 +-
>  config/common_linuxapp                             |   13 +-
>  doc/api/doxy-api-index.md                          |    1 +
>  doc/api/doxy-api.conf                              |    1 +
>  doc/guides/index.rst                               |    1 +
>  doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
>  doc/guides/rawdevs/index.rst                       |   14 +
>  doc/guides/rel_notes/release_18_05.rst             |    8 +
>  drivers/bus/fslmc/Makefile                         |    9 +-
>  drivers/bus/fslmc/fslmc_bus.c                      |    2 +
>  drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
>  drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
>  drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
>  drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
>  drivers/bus/fslmc/meson.build                      |    1 +
>  drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
>  drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
>  drivers/bus/fslmc/rte_fslmc.h                      |    2 +
>  drivers/meson.build                                |    3 +-
>  drivers/raw/Makefile                               |    3 +
>  drivers/raw/dpaa2_qdma/Makefile                    |   37 +
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002
> ++++++++++++++++++++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
>  drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
>  drivers/raw/dpaa2_qdma/meson.build                 |    9 +
>  drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
>  .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
>  drivers/raw/meson.build                            |    7 +
>  drivers/raw/skeleton_rawdev/meson.build            |    8 +
>  mk/rte.app.mk                                      |    3 +
>  31 files changed, 2512 insertions(+), 13 deletions(-)
>  create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
>  create mode 100644 doc/guides/rawdevs/index.rst
>  create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
>  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
>  create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
>  create mode 100644 drivers/raw/dpaa2_qdma/Makefile
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
>  create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
>  create mode 100644 drivers/raw/dpaa2_qdma/meson.build
>  create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
>  create mode 100644
> drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
>  create mode 100644 drivers/raw/meson.build
>  create mode 100644 drivers/raw/skeleton_rawdev/meson.build
> 
> --
> 1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 0/8] Introduce DPAA2 QDMA raw driver
  2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
                         ` (8 preceding siblings ...)
  2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
@ 2018-05-03 16:06       ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 1/8] raw: support meson build Nipun Gupta
                           ` (8 more replies)
  9 siblings, 9 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

This patch set introduces DPAA2 based QDMA device driver.

It provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.

This patch series is rebased on dpdk master branch

Patch 1:
  Support meson build in raw
Patches 2-4:
  Makes necessary changes in the DPAA2 bus
Patches 5-7:
  Add the DPAA2 QDMA driver
Patch 8:
  Update the documentation

Changes in v2:
  - Rebased over master branch
  - Pulled in couple of changes which were in CMDIF series
    - patch 3: some updations, patch 4
  - handle failues in device init correctly
  - Updated the logging, added DP logs
  - Fixed remove_hw_queues_from_list function

Changes in v3:
  - Fix compilation issue introduced due to a very recent change
    of removal of dma_addr_t. Fix in patch 7 where dma_addr_t
    was used.

Changes in v4:
  - Support meson build for raw and dpaa2 qdma (patch 1 & 5)
  - Merged the two separate doc patches (patch 8)

Changes in v5:
  - install user header file (rte_pmd_dpaa2_qdma.h) in case of
    meson build where it is introduced (patch 6). Previously
    it was added in patch 5.

Changes in v6:
  - Fix meson shared build

Changes in v7:
  - Fix x86 shared build

Nipun Gupta (8):
  raw: support meson build
  bus/fslmc: support MC DPDMAI object
  bus/fslmc: support scanning and probing of QDMA devices
  bus/fslmc: add macros required by QDMA for FLE and FD
  raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  raw/dpaa2_qdma: support configuration APIs
  raw/dpaa2_qdma: support enq and deq operations
  doc: add DPAA2 QDMA rawdev guide

 MAINTAINERS                                        |    9 +
 config/common_base                                 |    5 +
 config/common_linuxapp                             |    1 +
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/index.rst                               |    1 +
 doc/guides/rawdevs/dpaa2_qdma.rst                  |  140 +++
 doc/guides/rawdevs/index.rst                       |   14 +
 doc/guides/rel_notes/release_18_05.rst             |    8 +
 drivers/bus/fslmc/Makefile                         |    9 +-
 drivers/bus/fslmc/fslmc_bus.c                      |    2 +
 drivers/bus/fslmc/fslmc_vfio.c                     |    1 +
 drivers/bus/fslmc/mc/dpdmai.c                      |  429 +++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h                  |  189 ++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h              |  107 +++
 drivers/bus/fslmc/meson.build                      |    1 +
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h            |    8 +-
 drivers/bus/fslmc/rte_bus_fslmc_version.map        |    9 +
 drivers/bus/fslmc/rte_fslmc.h                      |    2 +
 drivers/meson.build                                |    3 +-
 drivers/raw/Makefile                               |    3 +
 drivers/raw/dpaa2_qdma/Makefile                    |   37 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 1002 ++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  150 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |   46 +
 drivers/raw/dpaa2_qdma/meson.build                 |    9 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  286 ++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   20 +
 drivers/raw/meson.build                            |    7 +
 drivers/raw/skeleton_rawdev/meson.build            |    8 +
 mk/rte.app.mk                                      |    3 +
 31 files changed, 2505 insertions(+), 6 deletions(-)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 1/8] raw: support meson build
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
                           ` (7 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
 drivers/meson.build                     | 3 ++-
 drivers/raw/meson.build                 | 7 +++++++
 drivers/raw/skeleton_rawdev/meson.build | 8 ++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/meson.build
 create mode 100644 drivers/raw/skeleton_rawdev/meson.build

diff --git a/drivers/meson.build b/drivers/meson.build
index b146f09..f879cb6 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -7,7 +7,8 @@ driver_classes = ['common',
 	       'mempool', # depends on common and bus.
 	       'net',     # depends on common, bus and mempool.
 	       'crypto',  # depends on common, bus and mempool (net in future).
-	       'event']   # depends on common, bus, mempool and net.
+	       'event',   # depends on common, bus, mempool and net.
+	       'raw']     # depends on common, bus, mempool, net and event.
 
 foreach class:driver_classes
 	drivers = []
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
new file mode 100644
index 0000000..24c82ff
--- /dev/null
+++ b/drivers/raw/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+drivers = ['skeleton_rawdev']
+std_deps = ['rawdev']
+config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
+driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/skeleton_rawdev/meson.build b/drivers/raw/skeleton_rawdev/meson.build
new file mode 100644
index 0000000..7cb2d3f
--- /dev/null
+++ b/drivers/raw/skeleton_rawdev/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
+sources = files('skeleton_rawdev.c',
+               'skeleton_rawdev_test.c')
+
+allow_experimental_apis = true
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 2/8] bus/fslmc: support MC DPDMAI object
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 1/8] raw: support meson build Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
                           ` (6 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain
  Cc: dev, Nipun Gupta, Cristian Sovaiala

This patch adds the DPDMAI (Data Path DMA Interface)
object support in MC driver.

Signed-off-by: Cristian Sovaiala <cristian.sovaiala@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/Makefile                  |   9 +-
 drivers/bus/fslmc/mc/dpdmai.c               | 429 ++++++++++++++++++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai.h           | 189 ++++++++++++
 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h       | 107 +++++++
 drivers/bus/fslmc/meson.build               |   1 +
 drivers/bus/fslmc/rte_bus_fslmc_version.map |   9 +
 6 files changed, 740 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/fslmc/mc/dpdmai.c
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai.h
 create mode 100644 drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h

diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile
index 3aa34e2..515d0f5 100644
--- a/drivers/bus/fslmc/Makefile
+++ b/drivers/bus/fslmc/Makefile
@@ -32,11 +32,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += \
 	mc/dpmng.c \
-        mc/dpbp.c \
-        mc/dpio.c \
-        mc/mc_sys.c \
+	mc/dpbp.c \
+	mc/dpio.c \
+	mc/mc_sys.c \
 	mc/dpcon.c \
-	mc/dpci.c
+	mc/dpci.c \
+	mc/dpdmai.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpio.c
 SRCS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += portal/dpaa2_hw_dpbp.c
diff --git a/drivers/bus/fslmc/mc/dpdmai.c b/drivers/bus/fslmc/mc/dpdmai.c
new file mode 100644
index 0000000..528889d
--- /dev/null
+++ b/drivers/bus/fslmc/mc/dpdmai.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <fsl_mc_sys.h>
+#include <fsl_mc_cmd.h>
+#include <fsl_dpdmai.h>
+#include <fsl_dpdmai_cmd.h>
+
+/**
+ * dpdmai_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_'
+ * @dpdmai_id:	DPDMAI 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 dpdmai_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 dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token)
+{
+	struct dpdmai_cmd_open *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
+					  cmd_flags,
+					  0);
+	cmd_params = (struct dpdmai_cmd_open *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_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);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI 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 dpdmai_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(DPDMAI_CMDID_CLOSE,
+					  cmd_flags, token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_create() - Create the DPDMAI 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 DPDMAI 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 dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id)
+{
+	struct dpdmai_cmd_create *cmd_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_create *)cmd.params;
+	cmd_params->priorities[0] = cfg->priorities[0];
+	cmd_params->priorities[1] = cfg->priorities[1];
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*obj_id = mc_cmd_read_object_id(&cmd);
+
+	return 0;
+}
+
+/**
+ * dpdmai_destroy() - Destroy the DPDMAI 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 dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id)
+{
+	struct dpdmai_cmd_destroy *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
+					  cmd_flags,
+					  dprc_token);
+	cmd_params = (struct dpdmai_cmd_destroy *)cmd.params;
+	cmd_params->dpdmai_id = cpu_to_le32(object_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_enable() - Enable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_ENABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_disable() - Disable the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_DISABLE,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_is_enabled() - Check if the DPDMAI 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 DPDMAI object
+ * @en:		Returns '1' if object is enabled; '0' otherwise
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en)
+{
+	struct dpdmai_rsp_is_enabled *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_IS_ENABLED,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_is_enabled *)cmd.params;
+	*en = dpdmai_get_field(rsp_params->en, ENABLE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_reset() - Reset the DPDMAI, 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 DPDMAI object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_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(DPDMAI_CMDID_RESET,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_get_attributes() - Retrieve DPDMAI 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 DPDMAI object
+ * @attr:	Returned object's attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr)
+{
+	struct dpdmai_rsp_get_attr *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_attr *)cmd.params;
+	attr->id = le32_to_cpu(rsp_params->id);
+	attr->num_of_priorities = rsp_params->num_of_priorities;
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation; use
+ *		DPDMAI_ALL_QUEUES to configure all Rx queues
+ *		identically.
+ * @cfg:	Rx queue configuration
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg)
+{
+	struct dpdmai_cmd_set_rx_queue *cmd_params;
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_set_rx_queue *)cmd.params;
+	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
+	cmd_params->dest_priority = cfg->dest_cfg.priority;
+	cmd_params->priority = priority;
+	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
+	cmd_params->options = cpu_to_le32(cfg->options);
+	dpdmai_set_field(cmd_params->dest_type,
+			 DEST_TYPE,
+			 cfg->dest_cfg.dest_type);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Rx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_rx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_rx_queue *)cmd.params;
+	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
+	attr->dest_cfg.priority = le32_to_cpu(rsp_params->dest_priority);
+	attr->dest_cfg.dest_type = dpdmai_get_field(rsp_params->dest_type,
+						    DEST_TYPE);
+
+	return 0;
+}
+
+/**
+ * dpdmai_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 DPDMAI object
+ * @priority:	Select the queue relative to number of
+ *		priorities configured at DPDMAI creation
+ * @attr:	Returned Tx queue attributes
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr)
+{
+	struct dpdmai_cmd_get_queue *cmd_params;
+	struct dpdmai_rsp_get_tx_queue *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpdmai_cmd_get_queue *)cmd.params;
+	cmd_params->priority = priority;
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
+	attr->fqid = le32_to_cpu(rsp_params->fqid);
+
+	return 0;
+}
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai.h b/drivers/bus/fslmc/mc/fsl_dpdmai.h
new file mode 100644
index 0000000..03e46ec
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __FSL_DPDMAI_H
+#define __FSL_DPDMAI_H
+
+struct fsl_mc_io;
+
+/* Data Path DMA Interface API
+ * Contains initialization APIs and runtime control APIs for DPDMAI
+ */
+
+/* General DPDMAI macros */
+
+/**
+ * Maximum number of Tx/Rx priorities per DPDMAI object
+ */
+#define DPDMAI_PRIO_NUM		2
+
+/**
+ * All queues considered; see dpdmai_set_rx_queue()
+ */
+#define DPDMAI_ALL_QUEUES	(uint8_t)(-1)
+
+int dpdmai_open(struct fsl_mc_io *mc_io,
+		uint32_t cmd_flags,
+		int dpdmai_id,
+		uint16_t *token);
+
+int dpdmai_close(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_cfg - Structure representing DPDMAI configuration
+ * @priorities: Priorities for the DMA hardware processing; valid priorities are
+ *	configured with values 1-8; the entry following last valid entry
+ *	should be configured with 0
+ */
+struct dpdmai_cfg {
+	uint8_t priorities[DPDMAI_PRIO_NUM];
+};
+
+int dpdmai_create(struct fsl_mc_io *mc_io,
+		  uint16_t dprc_token,
+		  uint32_t cmd_flags,
+		  const struct dpdmai_cfg *cfg,
+		  uint32_t *obj_id);
+
+int dpdmai_destroy(struct fsl_mc_io *mc_io,
+		   uint16_t dprc_token,
+		   uint32_t cmd_flags,
+		   uint32_t object_id);
+
+int dpdmai_enable(struct fsl_mc_io *mc_io,
+		  uint32_t cmd_flags,
+		  uint16_t token);
+
+int dpdmai_disable(struct fsl_mc_io *mc_io,
+		   uint32_t cmd_flags,
+		   uint16_t token);
+
+int dpdmai_is_enabled(struct fsl_mc_io *mc_io,
+		      uint32_t cmd_flags,
+		      uint16_t token,
+		      int *en);
+
+int dpdmai_reset(struct fsl_mc_io *mc_io,
+		 uint32_t cmd_flags,
+		 uint16_t token);
+
+/**
+ * struct dpdmai_attr - Structure representing DPDMAI attributes
+ * @id: DPDMAI object ID
+ * @num_of_priorities: number of priorities
+ */
+struct dpdmai_attr {
+	int id;
+	uint8_t num_of_priorities;
+};
+
+int dpdmai_get_attributes(struct fsl_mc_io *mc_io,
+			  uint32_t cmd_flags,
+			  uint16_t token,
+			  struct dpdmai_attr *attr);
+
+/**
+ * enum dpdmai_dest - DPDMAI destination types
+ * @DPDMAI_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
+ * @DPDMAI_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
+ * @DPDMAI_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 dpdmai_dest {
+	DPDMAI_DEST_NONE = 0,
+	DPDMAI_DEST_DPIO = 1,
+	DPDMAI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpdmai_dest_cfg - Structure representing DPDMAI 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 'DPDMAI_DEST_NONE' option
+ */
+struct dpdmai_dest_cfg {
+	enum dpdmai_dest dest_type;
+	int dest_id;
+	uint8_t priority;
+};
+
+/* DPDMAI queue modification options */
+
+/**
+ * Select to modify the user's context associated with the queue
+ */
+#define DPDMAI_QUEUE_OPT_USER_CTX	0x00000001
+
+/**
+ * Select to modify the queue's destination
+ */
+#define DPDMAI_QUEUE_OPT_DEST		0x00000002
+
+/**
+ * struct dpdmai_rx_queue_cfg - DPDMAI RX queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ *	Use any combination of 'DPDMAI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ *	dequeued frame;
+ *	valid only if 'DPDMAI_QUEUE_OPT_USER_CTX' is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ *	valid only if 'DPDMAI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpdmai_rx_queue_cfg {
+	uint32_t options;
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+
+};
+
+int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			const struct dpdmai_rx_queue_cfg *cfg);
+
+/**
+ * struct dpdmai_rx_queue_attr - Structure representing attributes of Rx queues
+ * @user_ctx:  User context value provided in the frame descriptor of each
+ *	 dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual FQID value to be used for dequeue operations
+ */
+struct dpdmai_rx_queue_attr {
+	uint64_t user_ctx;
+	struct dpdmai_dest_cfg dest_cfg;
+	uint32_t fqid;
+};
+
+int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_rx_queue_attr *attr);
+
+/**
+ * struct dpdmai_tx_queue_attr - Structure representing attributes of Tx queues
+ * @fqid: Virtual FQID to be used for sending frames to DMA hardware
+ */
+
+struct dpdmai_tx_queue_attr {
+	uint32_t fqid;
+};
+
+int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
+			uint32_t cmd_flags,
+			uint16_t token,
+			uint8_t priority,
+			struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
new file mode 100644
index 0000000..618e19e
--- /dev/null
+++ b/drivers/bus/fslmc/mc/fsl_dpdmai_cmd.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef _FSL_DPDMAI_CMD_H
+#define _FSL_DPDMAI_CMD_H
+
+/* DPDMAI Version */
+#define DPDMAI_VER_MAJOR		3
+#define DPDMAI_VER_MINOR		2
+
+/* Command versioning */
+#define DPDMAI_CMD_BASE_VERSION		1
+#define DPDMAI_CMD_ID_OFFSET		4
+
+#define DPDMAI_CMD(id)	((id << DPDMAI_CMD_ID_OFFSET) | DPDMAI_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPDMAI_CMDID_CLOSE		DPDMAI_CMD(0x800)
+#define DPDMAI_CMDID_OPEN		DPDMAI_CMD(0x80E)
+#define DPDMAI_CMDID_CREATE		DPDMAI_CMD(0x90E)
+#define DPDMAI_CMDID_DESTROY		DPDMAI_CMD(0x98E)
+#define DPDMAI_CMDID_GET_API_VERSION	DPDMAI_CMD(0xa0E)
+
+#define DPDMAI_CMDID_ENABLE		DPDMAI_CMD(0x002)
+#define DPDMAI_CMDID_DISABLE		DPDMAI_CMD(0x003)
+#define DPDMAI_CMDID_GET_ATTR		DPDMAI_CMD(0x004)
+#define DPDMAI_CMDID_RESET		DPDMAI_CMD(0x005)
+#define DPDMAI_CMDID_IS_ENABLED		DPDMAI_CMD(0x006)
+
+#define DPDMAI_CMDID_SET_RX_QUEUE	DPDMAI_CMD(0x1A0)
+#define DPDMAI_CMDID_GET_RX_QUEUE	DPDMAI_CMD(0x1A1)
+#define DPDMAI_CMDID_GET_TX_QUEUE	DPDMAI_CMD(0x1A2)
+
+/* Macros for accessing command fields smaller than 1byte */
+#define DPDMAI_MASK(field)        \
+	GENMASK(DPDMAI_##field##_SHIFT + DPDMAI_##field##_SIZE - 1, \
+		DPDMAI_##field##_SHIFT)
+#define dpdmai_set_field(var, field, val) \
+	((var) |= (((val) << DPDMAI_##field##_SHIFT) & DPDMAI_MASK(field)))
+#define dpdmai_get_field(var, field)      \
+	(((var) & DPDMAI_MASK(field)) >> DPDMAI_##field##_SHIFT)
+
+#pragma pack(push, 1)
+struct dpdmai_cmd_open {
+	uint32_t dpdmai_id;
+};
+
+struct dpdmai_cmd_create {
+	uint8_t pad;
+	uint8_t priorities[2];
+};
+
+struct dpdmai_cmd_destroy {
+	uint32_t dpdmai_id;
+};
+
+#define DPDMAI_ENABLE_SHIFT	0
+#define DPDMAI_ENABLE_SIZE	1
+
+struct dpdmai_rsp_is_enabled {
+	/* only the LSB bit */
+	uint8_t en;
+};
+
+struct dpdmai_rsp_get_attr {
+	uint32_t id;
+	uint8_t num_of_priorities;
+};
+
+#define DPDMAI_DEST_TYPE_SHIFT	0
+#define DPDMAI_DEST_TYPE_SIZE	4
+
+struct dpdmai_cmd_set_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t priority;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad;
+	uint64_t user_ctx;
+	uint32_t options;
+};
+
+struct dpdmai_cmd_get_queue {
+	uint8_t pad[5];
+	uint8_t priority;
+};
+
+struct dpdmai_rsp_get_rx_queue {
+	uint32_t dest_id;
+	uint8_t dest_priority;
+	uint8_t pad1;
+	/* from LSB: dest_type:4 */
+	uint8_t dest_type;
+	uint8_t pad2;
+	uint64_t user_ctx;
+	uint32_t fqid;
+};
+
+struct dpdmai_rsp_get_tx_queue {
+	uint64_t pad;
+	uint32_t fqid;
+};
+
+#pragma pack(pop)
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 890d6c0..22a56a6 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -11,6 +11,7 @@ sources = files('fslmc_bus.c',
 		'mc/dpbp.c',
 		'mc/dpci.c',
 		'mc/dpcon.c',
+		'mc/dpdmai.c',
 		'mc/dpio.c',
 		'mc/dpmng.c',
 		'mc/mc_sys.c',
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index f519651..70fb719 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -105,5 +105,14 @@ DPDK_18.05 {
 	global:
 
 	dpaa2_affine_qbman_ethrx_swp;
+	dpdmai_close;
+	dpdmai_disable;
+	dpdmai_enable;
+	dpdmai_get_attributes;
+	dpdmai_get_rx_queue;
+	dpdmai_get_tx_queue;
+	dpdmai_open;
+	dpdmai_set_rx_queue;
+	dpdmai_set_tx_queue;
 
 } DPDK_18.02;
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 3/8] bus/fslmc: support scanning and probing of QDMA devices
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 1/8] raw: support meson build Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
                           ` (5 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

'dpdmai' devices detected on fsl-mc bus are represented by DPAA2 QDMA
devices in DPDK.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/fslmc_bus.c  | 2 ++
 drivers/bus/fslmc/fslmc_vfio.c | 1 +
 drivers/bus/fslmc/rte_fslmc.h  | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 943c01b..fde5f19 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -164,6 +164,8 @@
 		dev->dev_type = DPAA2_CI;
 	else if (!strncmp("dpmcp", t_ptr, 5))
 		dev->dev_type = DPAA2_MPORTAL;
+	else if (!strncmp("dpdmai", t_ptr, 6))
+		dev->dev_type = DPAA2_QDMA;
 	else
 		dev->dev_type = DPAA2_UNKNOWN;
 
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 749d92d..3800c26 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -661,6 +661,7 @@ int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
 		switch (dev->dev_type) {
 		case DPAA2_ETH:
 		case DPAA2_CRYPTO:
+		case DPAA2_QDMA:
 			ret = fslmc_process_iodevices(dev);
 			if (ret) {
 				DPAA2_BUS_DEBUG("Dev (%s) init failed",
diff --git a/drivers/bus/fslmc/rte_fslmc.h b/drivers/bus/fslmc/rte_fslmc.h
index 69d0fec..7b34368 100644
--- a/drivers/bus/fslmc/rte_fslmc.h
+++ b/drivers/bus/fslmc/rte_fslmc.h
@@ -61,6 +61,7 @@ enum rte_dpaa2_dev_type {
 	DPAA2_IO,	/**< DPIO type device */
 	DPAA2_CI,	/**< DPCI type device */
 	DPAA2_MPORTAL,  /**< DPMCP type device */
+	DPAA2_QDMA,     /**< DPDMAI type device */
 	/* Unknown device placeholder */
 	DPAA2_UNKNOWN,
 	DPAA2_DEVTYPE_MAX,
@@ -91,6 +92,7 @@ struct rte_dpaa2_device {
 	union {
 		struct rte_eth_dev *eth_dev;        /**< ethernet device */
 		struct rte_cryptodev *cryptodev;    /**< Crypto Device */
+		struct rte_rawdev *rawdev;          /**< Raw Device */
 	};
 	enum rte_dpaa2_dev_type dev_type;   /**< Device Type */
 	uint16_t object_id;                 /**< DPAA2 Object ID */
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (2 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
                           ` (4 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e081afb..09ea603 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -188,7 +188,7 @@ enum qbman_fd_format {
 	((fd)->simple.frc = (0x80000000 | (len)))
 #define DPAA2_GET_FD_FRC_PARSE_SUM(fd)	\
 			((uint16_t)(((fd)->simple.frc & 0xffff0000) >> 16))
-#define DPAA2_SET_FD_FRC(fd, frc)	((fd)->simple.frc = frc)
+#define DPAA2_SET_FD_FRC(fd, _frc)	((fd)->simple.frc = _frc)
 #define DPAA2_RESET_FD_CTRL(fd)	 ((fd)->simple.ctrl = 0)
 
 #define	DPAA2_SET_FD_ASAL(fd, asal)	((fd)->simple.ctrl |= (asal << 16))
@@ -211,10 +211,12 @@ enum qbman_fd_format {
 } while (0)
 #define DPAA2_SET_FLE_OFFSET(fle, offset) \
 	((fle)->fin_bpid_offset |= (uint32_t)(offset) << 16)
+#define DPAA2_SET_FLE_LEN(fle, len)    ((fle)->length = len)
 #define DPAA2_SET_FLE_BPID(fle, bpid) ((fle)->fin_bpid_offset |= (size_t)bpid)
 #define DPAA2_GET_FLE_BPID(fle) ((fle)->fin_bpid_offset & 0x000000ff)
 #define DPAA2_SET_FLE_FIN(fle)	((fle)->fin_bpid_offset |= 1 << 31)
 #define DPAA2_SET_FLE_IVP(fle)   (((fle)->fin_bpid_offset |= 0x00004000))
+#define DPAA2_SET_FLE_BMT(fle)   (((fle)->fin_bpid_offset |= 0x00008000))
 #define DPAA2_SET_FD_COMPOUND_FMT(fd)	\
 	((fd)->simple.bpid_offset |= (uint32_t)1 << 28)
 #define DPAA2_GET_FD_ADDR(fd)	\
@@ -224,6 +226,10 @@ enum qbman_fd_format {
 #define DPAA2_GET_FD_BPID(fd)	(((fd)->simple.bpid_offset & 0x00003FFF))
 #define DPAA2_GET_FD_IVP(fd)   (((fd)->simple.bpid_offset & 0x00004000) >> 14)
 #define DPAA2_GET_FD_OFFSET(fd)	(((fd)->simple.bpid_offset & 0x0FFF0000) >> 16)
+#define DPAA2_GET_FD_FRC(fd)   ((fd)->simple.frc)
+#define DPAA2_GET_FD_FLC(fd) \
+	(((uint64_t)((fd)->simple.flc_hi) << 32) + (fd)->simple.flc_lo)
+#define DPAA2_GET_FD_ERR(fd)   ((fd)->simple.bpid_offset & 0x000000FF)
 #define DPAA2_GET_FLE_OFFSET(fle) (((fle)->fin_bpid_offset & 0x0FFF0000) >> 16)
 #define DPAA2_SET_FLE_SG_EXT(fle) ((fle)->fin_bpid_offset |= (uint64_t)1 << 29)
 #define DPAA2_IS_SET_FLE_SG_EXT(fle)	\
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (3 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
                           ` (3 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   5 +
 config/common_linuxapp                             |   1 +
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  35 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   7 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 473 insertions(+), 1 deletion(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index a482470..f8017d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -802,6 +802,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 03a8688..9b48bcb 100644
--- a/config/common_base
+++ b/config/common_base
@@ -618,6 +618,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 14e56cb..21b3fe3 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..68c785a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_mempool_dpaa2
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..b747500
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'mempool_dpaa2', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a60..26a6b0c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -251,6 +251,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 6/8] raw/dpaa2_qdma: support configuration APIs
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (4 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
                           ` (2 subsequent siblings)
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 doc/api/doxy-api-index.md                          |   1 +
 doc/api/doxy-api.conf                              |   1 +
 drivers/raw/dpaa2_qdma/Makefile                    |   2 +
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 375 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  63 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   2 +
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        | 216 ++++++++++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |  12 +
 8 files changed, 672 insertions(+)
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 26ce7b4..437d903 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -38,6 +38,7 @@ The public API headers are grouped by topics:
   [i40e]               (@ref rte_pmd_i40e.h),
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
+  [dpaa2_qdma]         (@ref rte_pmd_dpaa2_qdma.h),
   [crypto_scheduler]   (@ref rte_cryptodev_scheduler.h)
 
 - **memory**:
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index 5686cbb..88bee03 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           drivers/net/ixgbe \
                           drivers/net/softnic \
+                          drivers/raw/dpaa2_qdma \
                           lib/librte_eal/common/include \
                           lib/librte_eal/common/include/generic \
                           lib/librte_acl \
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index 68c785a..d88809e 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -32,4 +32,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV)-include += rte_pmd_dpaa2_qdma.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index 9288350..b38a282 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -20,6 +20,7 @@
 
 #include "dpaa2_qdma.h"
 #include "dpaa2_qdma_logs.h"
+#include "rte_pmd_dpaa2_qdma.h"
 
 /* Dynamic log type identifier */
 int dpaa2_qdma_logtype;
@@ -32,6 +33,380 @@
 static struct qdma_hw_queue_list qdma_queue_list
 	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
 
+/* QDMA Virtual Queues */
+struct qdma_virt_queue *qdma_vqs;
+
+/* QDMA per core data */
+struct qdma_per_core_info qdma_core_info[RTE_MAX_LCORE];
+
+static struct qdma_hw_queue *
+alloc_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_hw_queue *queue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Get a free queue from the list */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next) {
+		if (queue->num_users == 0) {
+			queue->lcore_id = lcore_id;
+			queue->num_users++;
+			break;
+		}
+	}
+
+	return queue;
+}
+
+static void
+free_hw_queue(struct qdma_hw_queue *queue)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	queue->num_users--;
+}
+
+
+static struct qdma_hw_queue *
+get_hw_queue(uint32_t lcore_id)
+{
+	struct qdma_per_core_info *core_info;
+	struct qdma_hw_queue *queue, *temp;
+	uint32_t least_num_users;
+	int num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	core_info = &qdma_core_info[lcore_id];
+	num_hw_queues = core_info->num_hw_queues;
+
+	/*
+	 * Allocate a HW queue if there are less queues
+	 * than maximum per core queues configured
+	 */
+	if (num_hw_queues < qdma_dev.max_hw_queues_per_core) {
+		queue = alloc_hw_queue(lcore_id);
+		if (queue) {
+			core_info->hw_queues[num_hw_queues] = queue;
+			core_info->num_hw_queues++;
+			return queue;
+		}
+	}
+
+	queue = core_info->hw_queues[0];
+	/* In case there is no queue associated with the core return NULL */
+	if (!queue)
+		return NULL;
+
+	/* Fetch the least loaded H/W queue */
+	least_num_users = core_info->hw_queues[0]->num_users;
+	for (i = 0; i < num_hw_queues; i++) {
+		temp = core_info->hw_queues[i];
+		if (temp->num_users < least_num_users)
+			queue = temp;
+	}
+
+	if (queue)
+		queue->num_users++;
+
+	return queue;
+}
+
+static void
+put_hw_queue(struct qdma_hw_queue *queue)
+{
+	struct qdma_per_core_info *core_info;
+	int lcore_id, num_hw_queues, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/*
+	 * If this is the last user of the queue free it.
+	 * Also remove it from QDMA core info.
+	 */
+	if (queue->num_users == 1) {
+		free_hw_queue(queue);
+
+		/* Remove the physical queue from core info */
+		lcore_id = queue->lcore_id;
+		core_info = &qdma_core_info[lcore_id];
+		num_hw_queues = core_info->num_hw_queues;
+		for (i = 0; i < num_hw_queues; i++) {
+			if (queue == core_info->hw_queues[i])
+				break;
+		}
+		for (; i < num_hw_queues - 1; i++)
+			core_info->hw_queues[i] = core_info->hw_queues[i + 1];
+		core_info->hw_queues[i] = NULL;
+	} else {
+		queue->num_users--;
+	}
+}
+
+int __rte_experimental
+rte_qdma_init(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_init(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_attr->num_hw_queues = qdma_dev.num_hw_queues;
+}
+
+int __rte_experimental
+rte_qdma_reset(void)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before reset.");
+		return -EBUSY;
+	}
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use && (qdma_vqs[i].num_enqueues !=
+		    qdma_vqs[i].num_dequeues))
+			DPAA2_QDMA_ERR("Jobs are still pending on VQ: %d", i);
+			return -EBUSY;
+	}
+
+	/* Reset HW queues */
+	TAILQ_FOREACH(queue, &qdma_queue_list, next)
+		queue->num_users = 0;
+
+	/* Reset and free virtual queues */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+	}
+	if (qdma_vqs)
+		rte_free(qdma_vqs);
+	qdma_vqs = NULL;
+
+	/* Reset per core info */
+	memset(&qdma_core_info, 0,
+		sizeof(struct qdma_per_core_info) * RTE_MAX_LCORE);
+
+	/* Free the FLE pool */
+	if (qdma_dev.fle_pool)
+		rte_mempool_free(qdma_dev.fle_pool);
+
+	/* Reset QDMA device structure */
+	qdma_dev.mode = RTE_QDMA_MODE_HW;
+	qdma_dev.max_hw_queues_per_core = 0;
+	qdma_dev.fle_pool = NULL;
+	qdma_dev.fle_pool_count = 0;
+	qdma_dev.max_vqs = 0;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config)
+{
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case QDMA device is not in stopped state, return -EBUSY */
+	if (qdma_dev.state == 1) {
+		DPAA2_QDMA_ERR(
+			"Device is in running state. Stop before config.");
+		return -1;
+	}
+
+	/* Reset the QDMA device */
+	ret = rte_qdma_reset();
+	if (ret) {
+		DPAA2_QDMA_ERR("Resetting QDMA failed");
+		return ret;
+	}
+
+	/* Set mode */
+	qdma_dev.mode = qdma_config->mode;
+
+	/* Set max HW queue per core */
+	if (qdma_config->max_hw_queues_per_core > MAX_HW_QUEUE_PER_CORE) {
+		DPAA2_QDMA_ERR("H/W queues per core is more than: %d",
+			       MAX_HW_QUEUE_PER_CORE);
+		return -EINVAL;
+	}
+	qdma_dev.max_hw_queues_per_core =
+		qdma_config->max_hw_queues_per_core;
+
+	/* Allocate Virtual Queues */
+	qdma_vqs = rte_malloc("qdma_virtual_queues",
+			(sizeof(struct qdma_virt_queue) * qdma_config->max_vqs),
+			RTE_CACHE_LINE_SIZE);
+	if (!qdma_vqs) {
+		DPAA2_QDMA_ERR("qdma_virtual_queues allocation failed");
+		return -ENOMEM;
+	}
+	qdma_dev.max_vqs = qdma_config->max_vqs;
+
+	/* Allocate FLE pool */
+	qdma_dev.fle_pool = rte_mempool_create("qdma_fle_pool",
+			qdma_config->fle_pool_count, QDMA_FLE_POOL_SIZE,
+			QDMA_FLE_CACHE_SIZE(qdma_config->fle_pool_count), 0,
+			NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
+	if (!qdma_dev.fle_pool) {
+		DPAA2_QDMA_ERR("qdma_fle_pool create failed");
+		rte_free(qdma_vqs);
+		qdma_vqs = NULL;
+		return -ENOMEM;
+	}
+	qdma_dev.fle_pool_count = qdma_config->fle_pool_count;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_start(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 1;
+
+	return 0;
+}
+
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags)
+{
+	char ring_name[32];
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	/* Get a free Virtual Queue */
+	for (i = 0; i < qdma_dev.max_vqs; i++) {
+		if (qdma_vqs[i].in_use == 0)
+			break;
+	}
+
+	/* Return in case no VQ is free */
+	if (i == qdma_dev.max_vqs) {
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	if (qdma_dev.mode == RTE_QDMA_MODE_HW ||
+			(flags & RTE_QDMA_VQ_EXCLUSIVE_PQ)) {
+		/* Allocate HW queue for a VQ */
+		qdma_vqs[i].hw_queue = alloc_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 1;
+	} else {
+		/* Allocate a Ring for Virutal Queue in VQ mode */
+		sprintf(ring_name, "status ring %d", i);
+		qdma_vqs[i].status_ring = rte_ring_create(ring_name,
+			qdma_dev.fle_pool_count, rte_socket_id(), 0);
+		if (!qdma_vqs[i].status_ring) {
+			DPAA2_QDMA_ERR("Status ring creation failed for vq");
+			rte_spinlock_unlock(&qdma_dev.lock);
+			return rte_errno;
+		}
+
+		/* Get a HW queue (shared) for a VQ */
+		qdma_vqs[i].hw_queue = get_hw_queue(lcore_id);
+		qdma_vqs[i].exclusive_hw_queue = 0;
+	}
+
+	if (qdma_vqs[i].hw_queue == NULL) {
+		DPAA2_QDMA_ERR("No H/W queue available for VQ");
+		if (qdma_vqs[i].status_ring)
+			rte_ring_free(qdma_vqs[i].status_ring);
+		qdma_vqs[i].status_ring = NULL;
+		rte_spinlock_unlock(&qdma_dev.lock);
+		return -ENODEV;
+	}
+
+	qdma_vqs[i].in_use = 1;
+	qdma_vqs[i].lcore_id = lcore_id;
+
+	rte_spinlock_unlock(&qdma_dev.lock);
+
+	return i;
+}
+
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_status)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (qdma_vq->in_use) {
+		vq_status->exclusive_hw_queue = qdma_vq->exclusive_hw_queue;
+		vq_status->lcore_id = qdma_vq->lcore_id;
+		vq_status->num_enqueues = qdma_vq->num_enqueues;
+		vq_status->num_dequeues = qdma_vq->num_dequeues;
+		vq_status->num_pending_jobs = vq_status->num_enqueues -
+				vq_status->num_dequeues;
+	}
+}
+
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* In case there are pending jobs on any VQ, return -EBUSY */
+	if (qdma_vq->num_enqueues != qdma_vq->num_dequeues)
+		return -EBUSY;
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	if (qdma_vq->exclusive_hw_queue)
+		free_hw_queue(qdma_vq->hw_queue);
+	else {
+		if (qdma_vqs->status_ring)
+			rte_ring_free(qdma_vqs->status_ring);
+
+		put_hw_queue(qdma_vq->hw_queue);
+	}
+
+	memset(qdma_vq, 0, sizeof(struct qdma_virt_queue));
+
+	rte_spinlock_lock(&qdma_dev.lock);
+
+	return 0;
+}
+
+void __rte_experimental
+rte_qdma_stop(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	qdma_dev.state = 0;
+}
+
+void __rte_experimental
+rte_qdma_destroy(void)
+{
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rte_qdma_reset();
+}
+
 static const struct rte_rawdev_ops dpaa2_qdma_ops;
 
 static int
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index 8b3b1b9..fe1da41 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -5,6 +5,22 @@
 #ifndef __DPAA2_QDMA_H__
 #define __DPAA2_QDMA_H__
 
+struct qdma_sdd;
+struct qdma_io_meta;
+
+#define DPAA2_QDMA_MAX_FLE 3
+#define DPAA2_QDMA_MAX_SDD 2
+
+/** FLE pool size: 3 Frame list + 2 source/destination descriptor */
+#define QDMA_FLE_POOL_SIZE (sizeof(struct qdma_io_meta) + \
+		sizeof(struct qbman_fle) * DPAA2_QDMA_MAX_FLE + \
+		sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD)
+/** FLE pool cache size */
+#define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
+
+/** Maximum possible H/W Queues on each core */
+#define MAX_HW_QUEUE_PER_CORE		64
+
 /**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
@@ -45,6 +61,53 @@ struct qdma_hw_queue {
 	uint32_t num_users;
 };
 
+/** Represents a QDMA virtual queue */
+struct qdma_virt_queue {
+	/** Status ring of the virtual queue */
+	struct rte_ring *status_ring;
+	/** Associated hw queue */
+	struct qdma_hw_queue *hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** States if this vq is in use or not */
+	uint8_t in_use;
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+};
+
+/** Represents a QDMA per core hw queues allocation in virtual mode */
+struct qdma_per_core_info {
+	/** list for allocated hw queues */
+	struct qdma_hw_queue *hw_queues[MAX_HW_QUEUE_PER_CORE];
+	/* Number of hw queues allocated for this core */
+	uint16_t num_hw_queues;
+};
+
+/** Metadata which is stored with each operation */
+struct qdma_io_meta {
+	/**
+	 * Context which is stored in the FLE pool (just before the FLE).
+	 * QDMA job is stored as a this context as a part of metadata.
+	 */
+	uint64_t cnxt;
+	/** VQ ID is stored as a part of metadata of the enqueue command */
+	 uint64_t id;
+};
+
+/** Source/Destination Descriptor */
+struct qdma_sdd {
+	uint32_t rsv;
+	/** Stride configuration */
+	uint32_t stride;
+	/** Route-by-port command */
+	uint32_t rbpcmd;
+	uint32_t cmd;
+} __attribute__((__packed__));
+
 /** Represents a DPDMAI raw device */
 struct dpaa2_dpdmai_dev {
 	/** Pointer to Next device instance */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
index b747500..a2eb1d2 100644
--- a/drivers/raw/dpaa2_qdma/meson.build
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -5,3 +5,5 @@ deps += ['rawdev', 'mempool_dpaa2', 'ring']
 sources = files('dpaa2_qdma.c')
 
 allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_qdma.h')
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
new file mode 100644
index 0000000..29a1e4b
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_QDMA_H__
+#define __RTE_PMD_DPAA2_QDMA_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 QDMA specific structures.
+ *
+ */
+
+/** Determines the mode of operation */
+enum {
+	/**
+	 * Allocate a H/W queue per VQ i.e. Exclusive hardware queue for a VQ.
+	 * This mode will have best performance.
+	 */
+	RTE_QDMA_MODE_HW,
+	/**
+	 * A VQ shall not have an exclusive associated H/W queue.
+	 * Rather a H/W Queue will be shared by multiple Virtual Queues.
+	 * This mode will have intermediate data structures to support
+	 * multi VQ to PQ mappings thus having some performance implications.
+	 * Note: Even in this mode there is an option to allocate a H/W
+	 * queue for a VQ. Please see 'RTE_QDMA_VQ_EXCLUSIVE_PQ' flag.
+	 */
+	RTE_QDMA_MODE_VIRTUAL
+};
+
+/**
+ * If user has configued a Virtual Queue mode, but for some particular VQ
+ * user needs an exclusive H/W queue associated (for better performance
+ * on that particular VQ), then user can pass this flag while creating the
+ * Virtual Queue. A H/W queue will be allocated corresponding to
+ * VQ which uses this flag.
+ */
+#define RTE_QDMA_VQ_EXCLUSIVE_PQ	(1ULL)
+
+/** States if the source addresses is physical. */
+#define RTE_QDMA_JOB_SRC_PHY		(1ULL)
+
+/** States if the destination addresses is physical. */
+#define RTE_QDMA_JOB_DEST_PHY		(1ULL << 1)
+
+/** Provides QDMA device attributes */
+struct rte_qdma_attr {
+	/** total number of hw QDMA queues present */
+	uint16_t num_hw_queues;
+};
+
+/** QDMA device configuration structure */
+struct rte_qdma_config {
+	/** Number of maximum hw queues to allocate per core. */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's to be used. */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/**
+	 * User provides this as input to the driver as a size of the FLE pool.
+	 * FLE's (and corresponding source/destination descriptors) are
+	 * allocated by the driver at enqueue time to store src/dest and
+	 * other data and are freed at the dequeue time. This determines the
+	 * maximum number of inflight jobs on the QDMA device. This should
+	 * be power of 2.
+	 */
+	int fle_pool_count;
+};
+
+/** Provides QDMA device statistics */
+struct rte_qdma_vq_stats {
+	/** States if this vq has exclusively associated hw queue */
+	uint8_t exclusive_hw_queue;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/* Total number of enqueues on this VQ */
+	uint64_t num_enqueues;
+	/* Total number of dequeues from this VQ */
+	uint64_t num_dequeues;
+	/* total number of pending jobs in this VQ */
+	uint64_t num_pending_jobs;
+};
+
+/** Determines a QDMA job */
+struct rte_qdma_job {
+	/** Source Address from where DMA is (to be) performed */
+	uint64_t src;
+	/** Destination Address where DMA is (to be) done */
+	uint64_t dest;
+	/** Length of the DMA operation in bytes. */
+	uint32_t len;
+	/** See RTE_QDMA_JOB_ flags */
+	uint32_t flags;
+	/**
+	 * User can specify a context which will be maintained
+	 * on the dequeue operation.
+	 */
+	uint64_t cnxt;
+	/**
+	 * Status of the transaction.
+	 * This is filled in the dequeue operation by the driver.
+	 */
+	uint8_t status;
+};
+
+/**
+ * Initialize the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_init(void);
+
+/**
+ * Get the QDMA attributes.
+ *
+ * @param qdma_attr
+ *   QDMA attributes providing total number of hw queues etc.
+ */
+void __rte_experimental
+rte_qdma_attr_get(struct rte_qdma_attr *qdma_attr);
+
+/**
+ * Reset the QDMA device. This API will completely reset the QDMA
+ * device, bringing it to original state as if only rte_qdma_init() API
+ * has been called.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_reset(void);
+
+/**
+ * Configure the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_configure(struct rte_qdma_config *qdma_config);
+
+/**
+ * Start the QDMA device.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_start(void);
+
+/**
+ * Create a Virtual Queue on a particular lcore id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param lcore_id
+ *   LCORE ID on which this particular queue would be associated with.
+ * @param flags
+ *  RTE_QDMA_VQ_ flags. See macro definitions.
+ *
+ * @returns
+ *   - >= 0: Virtual queue ID.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
+
+/**
+ * Get a Virtual Queue statistics.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param vq_stats
+ *   VQ statistics structure which will be filled in by the driver.
+ */
+void __rte_experimental
+rte_qdma_vq_stats(uint16_t vq_id,
+		  struct rte_qdma_vq_stats *vq_stats);
+
+/**
+ * Destroy the Virtual Queue specified by vq_id.
+ * This API can be called from any thread/core. User can create/destroy
+ * VQ's at runtime.
+ *
+ * @param vq_id
+ *   Virtual Queue ID which needs to be deinialized.
+ *
+ * @returns
+ *   - 0: Success.
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_destroy(uint16_t vq_id);
+
+/**
+ * Stop QDMA device.
+ */
+void __rte_experimental
+rte_qdma_stop(void);
+
+/**
+ * Destroy the QDMA device.
+ */
+void __rte_experimental
+rte_qdma_destroy(void);
+
+#endif /* __RTE_PMD_DPAA2_QDMA_H__*/
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 33d2379..7335c35 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -1,4 +1,16 @@
 EXPERIMENTAL {
+	global:
+
+	rte_qdma_attr_get;
+	rte_qdma_configure;
+	rte_qdma_destroy;
+	rte_qdma_init;
+	rte_qdma_reset;
+	rte_qdma_start;
+	rte_qdma_stop;
+	rte_qdma_vq_create;
+	rte_qdma_vq_destroy;
+	rte_qdma_vq_stats;
 
 	local: *;
 };
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 7/8] raw/dpaa2_qdma: support enq and deq operations
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (5 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
  2018-05-08 10:22         ` [dpdk-dev] [PATCH RESEND v7 0/8] Introduce DPAA2 QDMA raw driver Thomas Monjalon
  8 siblings, 0 replies; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 333 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  21 ++
 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h        |  70 +++++
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 4 files changed, 428 insertions(+)

diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
index b38a282..1d15c30 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -344,6 +344,339 @@
 	return i;
 }
 
+static void
+dpaa2_qdma_populate_fle(struct qbman_fle *fle,
+			uint64_t src, uint64_t dest,
+			size_t len, uint32_t flags)
+{
+	struct qdma_sdd *sdd;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	sdd = (struct qdma_sdd *)((uint8_t *)(fle) +
+		(DPAA2_QDMA_MAX_FLE * sizeof(struct qbman_fle)));
+
+	/* first frame list to source descriptor */
+	DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(sdd));
+	DPAA2_SET_FLE_LEN(fle, (2 * (sizeof(struct qdma_sdd))));
+
+	/* source and destination descriptor */
+	DPAA2_SET_SDD_RD_COHERENT(sdd); /* source descriptor CMD */
+	sdd++;
+	DPAA2_SET_SDD_WR_COHERENT(sdd); /* dest descriptor CMD */
+
+	fle++;
+	/* source frame list to source buffer */
+	if (flags & RTE_QDMA_JOB_SRC_PHY) {
+		DPAA2_SET_FLE_ADDR(fle, src);
+		DPAA2_SET_FLE_BMT(fle);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(src));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	fle++;
+	/* destination frame list to destination buffer */
+	if (flags & RTE_QDMA_JOB_DEST_PHY) {
+		DPAA2_SET_FLE_BMT(fle);
+		DPAA2_SET_FLE_ADDR(fle, dest);
+	} else {
+		DPAA2_SET_FLE_ADDR(fle, DPAA2_VADDR_TO_IOVA(dest));
+	}
+	DPAA2_SET_FLE_LEN(fle, len);
+
+	/* Final bit: 1, for last frame list */
+	DPAA2_SET_FLE_FIN(fle);
+}
+
+static int
+dpdmai_dev_enqueue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t txq_id,
+		   uint16_t vq_id,
+		   struct rte_qdma_job *job)
+{
+	struct qdma_io_meta *io_meta;
+	struct qbman_fd fd;
+	struct dpaa2_queue *txq;
+	struct qbman_fle *fle;
+	struct qbman_eq_desc eqdesc;
+	struct qbman_swp *swp;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	txq = &(dpdmai_dev->tx_queue[txq_id]);
+
+	/* Prepare enqueue descriptor */
+	qbman_eq_desc_clear(&eqdesc);
+	qbman_eq_desc_set_fq(&eqdesc, txq->fqid);
+	qbman_eq_desc_set_no_orp(&eqdesc, 0);
+	qbman_eq_desc_set_response(&eqdesc, 0, 0);
+
+	/*
+	 * Get an FLE/SDD from FLE pool.
+	 * Note: IO metadata is before the FLE and SDD memory.
+	 */
+	ret = rte_mempool_get(qdma_dev.fle_pool, (void **)(&io_meta));
+	if (ret) {
+		DPAA2_QDMA_DP_WARN("Memory alloc failed for FLE");
+		return ret;
+	}
+
+	/* Set the metadata */
+	io_meta->cnxt = (size_t)job;
+	io_meta->id = vq_id;
+
+	fle = (struct qbman_fle *)(io_meta + 1);
+
+	/* populate Frame descriptor */
+	memset(&fd, 0, sizeof(struct qbman_fd));
+	DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(fle));
+	DPAA2_SET_FD_COMPOUND_FMT(&fd);
+	DPAA2_SET_FD_FRC(&fd, QDMA_SER_CTX);
+
+	/* Populate FLE */
+	memset(fle, 0, QDMA_FLE_POOL_SIZE);
+	dpaa2_qdma_populate_fle(fle, job->src, job->dest, job->len, job->flags);
+
+	/* Enqueue the packet to the QBMAN */
+	do {
+		ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+		if (ret < 0 && ret != -EBUSY)
+			DPAA2_QDMA_ERR("Transmit failure with err: %d", ret);
+	} while (ret == -EBUSY);
+
+	DPAA2_QDMA_DP_DEBUG("Successfully transmitted a packet");
+
+	return ret;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i, ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		ret = rte_qdma_vq_enqueue(vq_id, job[i]);
+		if (ret < 0)
+			break;
+	}
+
+	return i;
+}
+
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != qdma_vq->lcore_id) {
+		DPAA2_QDMA_ERR("QDMA enqueue for vqid %d on wrong core",
+				vq_id);
+		return -EINVAL;
+	}
+
+	ret = dpdmai_dev_enqueue(dpdmai_dev, qdma_pq->queue_id, vq_id, job);
+	if (ret < 0) {
+		DPAA2_QDMA_ERR("DPDMAI device enqueue failed: %d", ret);
+		return ret;
+	}
+
+	qdma_vq->num_enqueues++;
+
+	return 1;
+}
+
+/* Function to receive a QDMA job for a given device and queue*/
+static int
+dpdmai_dev_dequeue(struct dpaa2_dpdmai_dev *dpdmai_dev,
+		   uint16_t rxq_id,
+		   uint16_t *vq_id,
+		   struct rte_qdma_job **job)
+{
+	struct qdma_io_meta *io_meta;
+	struct dpaa2_queue *rxq;
+	struct qbman_result *dq_storage;
+	struct qbman_pull_desc pulldesc;
+	const struct qbman_fd *fd;
+	struct qbman_swp *swp;
+	struct qbman_fle *fle;
+	uint32_t fqid;
+	uint8_t status;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+		ret = dpaa2_affine_qbman_swp();
+		if (ret) {
+			DPAA2_QDMA_ERR("Failure in affining portal");
+			return 0;
+		}
+	}
+	swp = DPAA2_PER_LCORE_PORTAL;
+
+	rxq = &(dpdmai_dev->rx_queue[rxq_id]);
+	dq_storage = rxq->q_storage->dq_storage[0];
+	fqid = rxq->fqid;
+
+	/* Prepare dequeue descriptor */
+	qbman_pull_desc_clear(&pulldesc);
+	qbman_pull_desc_set_fq(&pulldesc, fqid);
+	qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+		(uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+	qbman_pull_desc_set_numframes(&pulldesc, 1);
+
+	while (1) {
+		if (qbman_swp_pull(swp, &pulldesc)) {
+			DPAA2_QDMA_DP_WARN("VDQ command not issued. QBMAN busy");
+			continue;
+		}
+		break;
+	}
+
+	/* Check if previous issued command is completed. */
+	while (!qbman_check_command_complete(dq_storage))
+		;
+	/* Loop until dq_storage is updated with new token by QBMAN */
+	while (!qbman_check_new_result(dq_storage))
+		;
+
+	/* Check for valid frame. */
+	status = qbman_result_DQ_flags(dq_storage);
+	if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+		DPAA2_QDMA_DP_DEBUG("No frame is delivered");
+		return 0;
+	}
+
+	/* Get the FD */
+	fd = qbman_result_DQ_fd(dq_storage);
+
+	/*
+	 * Fetch metadata from FLE. job and vq_id were set
+	 * in metadata in the enqueue operation.
+	 */
+	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
+	io_meta = (struct qdma_io_meta *)(fle) - 1;
+	if (vq_id)
+		*vq_id = io_meta->id;
+
+	*job = (struct rte_qdma_job *)(size_t)io_meta->cnxt;
+	(*job)->status = DPAA2_GET_FD_ERR(fd);
+
+	/* Free FLE to the pool */
+	rte_mempool_put(qdma_dev.fle_pool, io_meta);
+
+	DPAA2_QDMA_DP_DEBUG("packet received");
+
+	return 1;
+}
+
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs)
+{
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < nb_jobs; i++) {
+		job[i] = rte_qdma_vq_dequeue(vq_id);
+		if (!job[i])
+			break;
+	}
+
+	return i;
+}
+
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id)
+{
+	struct qdma_virt_queue *qdma_vq = &qdma_vqs[vq_id];
+	struct qdma_hw_queue *qdma_pq = qdma_vq->hw_queue;
+	struct dpaa2_dpdmai_dev *dpdmai_dev = qdma_pq->dpdmai_dev;
+	struct rte_qdma_job *job = NULL;
+	struct qdma_virt_queue *temp_qdma_vq;
+	int dequeue_budget = QDMA_DEQUEUE_BUDGET;
+	int ring_count, ret, i;
+	uint16_t temp_vq_id;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* Return error in case of wrong lcore_id */
+	if (rte_lcore_id() != (unsigned int)(qdma_vq->lcore_id)) {
+		DPAA2_QDMA_ERR("QDMA dequeue for vqid %d on wrong core",
+				vq_id);
+		return NULL;
+	}
+
+	/* Only dequeue when there are pending jobs on VQ */
+	if (qdma_vq->num_enqueues == qdma_vq->num_dequeues)
+		return NULL;
+
+	if (qdma_vq->exclusive_hw_queue) {
+		/* In case of exclusive queue directly fetch from HW queue */
+		ret = dpdmai_dev_dequeue(dpdmai_dev, qdma_pq->queue_id,
+					 NULL, &job);
+		if (ret < 0) {
+			DPAA2_QDMA_ERR(
+				"Dequeue from DPDMAI device failed: %d", ret);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Get the QDMA completed jobs from the software ring.
+		 * In case they are not available on the ring poke the HW
+		 * to fetch completed jobs from corresponding HW queues
+		 */
+		ring_count = rte_ring_count(qdma_vq->status_ring);
+		if (ring_count == 0) {
+			/* TODO - How to have right budget */
+			for (i = 0; i < dequeue_budget; i++) {
+				ret = dpdmai_dev_dequeue(dpdmai_dev,
+					qdma_pq->queue_id, &temp_vq_id, &job);
+				if (ret == 0)
+					break;
+				temp_qdma_vq = &qdma_vqs[temp_vq_id];
+				rte_ring_enqueue(temp_qdma_vq->status_ring,
+					(void *)(job));
+				ring_count = rte_ring_count(
+					qdma_vq->status_ring);
+				if (ring_count)
+					break;
+			}
+		}
+
+		/* Dequeue job from the software ring to provide to the user */
+		rte_ring_dequeue(qdma_vq->status_ring, (void **)&job);
+		if (job)
+			qdma_vq->num_dequeues++;
+	}
+
+	return job;
+}
+
 void __rte_experimental
 rte_qdma_vq_stats(uint16_t vq_id,
 		  struct rte_qdma_vq_stats *vq_status)
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
index fe1da41..c6a0578 100644
--- a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -18,10 +18,31 @@
 /** FLE pool cache size */
 #define QDMA_FLE_CACHE_SIZE(_num) (_num/(RTE_MAX_LCORE * 2))
 
+/** Notification by FQD_CTX[fqid] */
+#define QDMA_SER_CTX (1 << 8)
+
+/**
+ * Source descriptor command read transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_RD_COHERENT(sdd) ((sdd)->cmd = (0xb << 28))
+/**
+ * Destination descriptor command write transaction type for RBP=0:
+ * coherent copy of cacheable memory
+ */
+#define DPAA2_SET_SDD_WR_COHERENT(sdd) ((sdd)->cmd = (0x6 << 28))
+
 /** Maximum possible H/W Queues on each core */
 #define MAX_HW_QUEUE_PER_CORE		64
 
 /**
+ * In case of Virtual Queue mode, this specifies the number of
+ * dequeue the 'qdma_vq_dequeue/multi' API does from the H/W Queue
+ * in case there is no job present on the Virtual Queue ring.
+ */
+#define QDMA_DEQUEUE_BUDGET		64
+
+/**
  * Represents a QDMA device.
  * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
  */
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
index 29a1e4b..17fffcb 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma.h
@@ -175,6 +175,76 @@ struct rte_qdma_job {
 rte_qdma_vq_create(uint32_t lcore_id, uint32_t flags);
 
 /**
+ * Enqueue multiple jobs to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA jobs provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs containing relevant information related to DMA.
+ * @param nb_jobs
+ *   Number of QDMA jobs provided by the user.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Enqueue a single job to a Virtual Queue.
+ * If the enqueue is successful, the H/W will perform DMA operations
+ * on the basis of the QDMA job provided.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   A QDMA Job containing relevant information related to DMA.
+ *
+ * @returns
+ *   - >=0: Number of jobs successfully submitted
+ *   - <0: Error code.
+ */
+int __rte_experimental
+rte_qdma_vq_enqueue(uint16_t vq_id,
+		    struct rte_qdma_job *job);
+
+/**
+ * Dequeue multiple completed jobs from a Virtual Queue.
+ * Provides the list of completed jobs capped by nb_jobs.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ * @param job
+ *   List of QDMA Jobs returned from the API.
+ * @param nb_jobs
+ *   Number of QDMA jobs requested for dequeue by the user.
+ *
+ * @returns
+ *   Number of jobs actually dequeued.
+ */
+int __rte_experimental
+rte_qdma_vq_dequeue_multi(uint16_t vq_id,
+			  struct rte_qdma_job **job,
+			  uint16_t nb_jobs);
+
+/**
+ * Dequeue a single completed jobs from a Virtual Queue.
+ *
+ * @param vq_id
+ *   Virtual Queue ID.
+ *
+ * @returns
+ *   - A completed job or NULL if no job is there.
+ */
+struct rte_qdma_job * __rte_experimental
+rte_qdma_vq_dequeue(uint16_t vq_id);
+
+/**
  * Get a Virtual Queue statistics.
  *
  * @param vq_id
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
index 7335c35..fe42a22 100644
--- a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -10,6 +10,10 @@ EXPERIMENTAL {
 	rte_qdma_stop;
 	rte_qdma_vq_create;
 	rte_qdma_vq_destroy;
+	rte_qdma_vq_dequeue;
+	rte_qdma_vq_dequeue_multi;
+	rte_qdma_vq_enqueue;
+	rte_qdma_vq_enqueue_multi;
 	rte_qdma_vq_stats;
 
 	local: *;
-- 
1.9.1

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

* [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (6 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
@ 2018-05-03 16:06         ` Nipun Gupta
  2018-05-08 10:17           ` Thomas Monjalon
  2018-05-08 10:22         ` [dpdk-dev] [PATCH RESEND v7 0/8] Introduce DPAA2 QDMA raw driver Thomas Monjalon
  8 siblings, 1 reply; 95+ messages in thread
From: Nipun Gupta @ 2018-05-03 16:06 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                            |   1 +
 doc/guides/index.rst                   |   1 +
 doc/guides/rawdevs/dpaa2_qdma.rst      | 140 +++++++++++++++++++++++++++++++++
 doc/guides/rawdevs/index.rst           |  14 ++++
 doc/guides/rel_notes/release_18_05.rst |   8 ++
 5 files changed, 164 insertions(+)
 create mode 100644 doc/guides/rawdevs/dpaa2_qdma.rst
 create mode 100644 doc/guides/rawdevs/index.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index f8017d3..b72b048 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -808,6 +808,7 @@ Rawdev Drivers
 NXP DPAA2 QDMA
 M: Nipun Gupta <nipun.gupta@nxp.com>
 F: drivers/raw/dpaa2_qdma/
+F: doc/guides/rawdevs/dpaa2_qdma.rst
 
 
 Eventdev Drivers
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index d60529d..a93baac 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -20,6 +20,7 @@ DPDK documentation
    eventdevs/index
    mempool/index
    platform/index
+   rawdevs/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/rawdevs/dpaa2_qdma.rst b/doc/guides/rawdevs/dpaa2_qdma.rst
new file mode 100644
index 0000000..b9bc4ec
--- /dev/null
+++ b/doc/guides/rawdevs/dpaa2_qdma.rst
@@ -0,0 +1,140 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+NXP DPAA2 QDMA Driver
+=====================
+
+The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+to initiate a DMA transaction from CPU. The initiated DMA is performed
+without CPU being involved in the actual DMA transaction. This is achieved
+via using the DPDMAI device exposed by MC.
+
+More information can be found at `NXP Official Website
+<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.
+
+Features
+--------
+
+The DPAA2 QDMA implements following features in the rawdev API;
+
+- Supports issuing DMA of data within memory without hogging CPU while
+  performing DMA operation.
+- Supports configuring to optionally get status of the DMA translation on
+  per DMA operation basis.
+
+Supported DPAA2 SoCs
+--------------------
+
+- LS2084A/LS2044A
+- LS2088A/LS2048A
+- LS1088A/LS1048A
+
+Prerequisites
+-------------
+
+There are three main pre-requisities for executing DPAA2 QDMA on a DPAA2
+compatible board:
+
+1. **ARM 64 Tool Chain**
+
+   For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/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 QDMA 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 Extra Scripts**
+
+  DPAA2 based resources can be configured easily with the help of ready scripts
+  as provided in the DPDK Extra repository.
+
+  `DPDK Extras Scripts <https://github.com/qoriq-open-source/dpdk-extras>`_.
+
+Currently supported by DPDK:
+
+- NXP LSDK **17.12+**.
+- MC Firmware version **10.3.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.
+
+- ``CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV`` (default ``y``)
+
+  Toggle compilation of the ``lrte_pmd_dpaa2_qdma`` driver.
+
+Enabling logs
+-------------
+
+For enabling logs, use the following EAL parameter:
+
+.. code-block:: console
+
+   ./your_qdma_application <EAL args> --log-level=pmd.raw.dpaa2.qdma,<level>
+
+Using ``pmd.raw.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
+enabled which are lower than logging ``level``.
+
+Driver Compilation
+~~~~~~~~~~~~~~~~~~
+
+To compile the DPAA2 QDMA 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
+
+Initialization
+--------------
+
+The DPAA2 QDMA is exposed as a vdev device which consists of dpdmai devices.
+On EAL initialization, dpdmai devices will be probed and populated into the
+rawdevices. The rawdev ID of the device can be obtained using
+
+* Invoking ``rte_rawdev_get_dev_id("dpdmai.x")`` from the application
+  where x is the object ID of the DPDMAI object created by MC. Use can
+  use this index for further rawdev function calls.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
+``Supported DPAA2 SoCs``.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
new file mode 100644
index 0000000..29b4f6c
--- /dev/null
+++ b/doc/guides/rawdevs/index.rst
@@ -0,0 +1,14 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 NXP
+
+Rawdev Drivers
+==============
+
+The following are a list of raw device PMDs, which can be used from an
+application through rawdev API.
+
+.. toctree::
+    :maxdepth: 2
+    :numbered:
+
+    dpaa2_qdma
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..22fa74d 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -164,6 +164,14 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
+* **Added DPAA2 QDMA Driver (in rawdev).**
+
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
+  to initiate a DMA transaction from CPU. The initiated DMA is performed
+  without CPU being involved in the actual DMA transaction.
+
+  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
+
 
 API Changes
 -----------
-- 
1.9.1

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

* Re: [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-08 10:17           ` Thomas Monjalon
  0 siblings, 0 replies; 95+ messages in thread
From: Thomas Monjalon @ 2018-05-08 10:17 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev, hemant.agrawal, shreyansh.jain

03/05/2018 18:06, Nipun Gupta:
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> +* **Added DPAA2 QDMA Driver (in rawdev).**
> +
> +  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
> +  to initiate a DMA transaction from CPU. The initiated DMA is performed
> +  without CPU being involved in the actual DMA transaction.
> +
> +  See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.

Adding this line in the release notes:

   + librte_pmd_dpaa2_qdma.so.1

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

* Re: [dpdk-dev] [PATCH RESEND v7 0/8] Introduce DPAA2 QDMA raw driver
  2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
                           ` (7 preceding siblings ...)
  2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
@ 2018-05-08 10:22         ` Thomas Monjalon
  8 siblings, 0 replies; 95+ messages in thread
From: Thomas Monjalon @ 2018-05-08 10:22 UTC (permalink / raw)
  To: Nipun Gupta; +Cc: dev, hemant.agrawal, shreyansh.jain

03/05/2018 18:06, Nipun Gupta:
> This patch set introduces DPAA2 based QDMA device driver.
> 
> It provide means to initiate a DMA transaction from CPU.
> The initiated DMA is performed without CPU being involved
> in the actual DMA transaction.

Applied, thanks

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

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

Thread overview: 95+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-07 15:16 [dpdk-dev] [PATCH 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-04-07 15:16 ` [dpdk-dev] [PATCH 1/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-04-16 11:46   ` Shreyansh Jain
2018-04-07 15:16 ` [dpdk-dev] [PATCH 2/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-04-16 11:58   ` Shreyansh Jain
2018-04-07 15:16 ` [dpdk-dev] [PATCH 3/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-04-16 12:23   ` Shreyansh Jain
2018-04-07 15:17 ` [dpdk-dev] [PATCH 4/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-04-16 13:46   ` Shreyansh Jain
2018-04-07 15:17 ` [dpdk-dev] [PATCH 5/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-04-07 15:17 ` [dpdk-dev] [PATCH 6/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-04-16 14:01   ` Shreyansh Jain
2018-04-07 15:17 ` [dpdk-dev] [PATCH 7/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-04-16 14:04   ` Shreyansh Jain
2018-04-07 15:17 ` [dpdk-dev] [PATCH 8/8] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
2018-04-20  4:04 ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 1/9 v2] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 2/9 v2] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 3/9 v2] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-04-20  9:17     ` Hemant Agrawal
2018-04-20  4:04   ` [dpdk-dev] [PATCH 4/9 v2] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 5/9 v2] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 6/9 v2] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 7/9 v2] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 8/9 v2] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-04-20  4:04   ` [dpdk-dev] [PATCH 9/9 v2] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
2018-04-20  4:10   ` [dpdk-dev] [PATCH 0/9 v2] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-04-20 10:34     ` Nipun Gupta
2018-04-20 10:30 ` [dpdk-dev] [PATCH 0/9 v3] " Nipun Gupta
2018-04-20 10:30   ` [dpdk-dev] [PATCH 1/9 v3] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-04-20 10:30   ` [dpdk-dev] [PATCH 2/9 v3] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-04-20 10:30   ` [dpdk-dev] [PATCH 3/9 v3] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-04-20 10:30   ` [dpdk-dev] [PATCH 4/9 v3] bus/fslmc: fix typecasting in IOVA/virt conversion macros Nipun Gupta
2018-04-20 10:31   ` [dpdk-dev] [PATCH 5/9 v3] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-04-20 10:31   ` [dpdk-dev] [PATCH 6/9 v3] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-04-20 10:31   ` [dpdk-dev] [PATCH 7/9 v3] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-04-20 10:31   ` [dpdk-dev] [PATCH 8/9 v3] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-04-20 10:31   ` [dpdk-dev] [PATCH 9/9 v3] doc: add dpaa2 qdma rawdev to release notes Nipun Gupta
2018-04-23  0:03     ` Thomas Monjalon
2018-04-23  8:45       ` Nipun Gupta
2018-04-23  0:05   ` [dpdk-dev] [PATCH 0/9 v3] Introduce DPAA2 QDMA raw driver Thomas Monjalon
2018-04-23  8:46     ` Nipun Gupta
2018-04-24 11:49 ` [dpdk-dev] [PATCH 0/8 v4] " Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 1/8 v4] raw: support meson build Nipun Gupta
2018-04-26  6:58     ` Shreyansh Jain
2018-04-24 11:49   ` [dpdk-dev] [PATCH 2/8 v4] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 3/8 v4] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 4/8 v4] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 5/8 v4] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-04-30 12:34     ` Thomas Monjalon
2018-05-01  6:14       ` Nipun Gupta
2018-05-01  6:21         ` Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 6/8 v4] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 7/8 v4] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-04-24 11:49   ` [dpdk-dev] [PATCH 8/8 v4] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-05-01  9:58   ` [dpdk-dev] [PATCH v5 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 1/8] raw: support meson build Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-05-01  9:58     ` [dpdk-dev] [PATCH v5 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-05-02 17:09     ` [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 1/8] raw: support meson build Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-05-03 14:07         ` Shreyansh Jain
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-05-02 17:09       ` [dpdk-dev] [PATCH v6 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-05-03 15:51       ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 1/8] raw: support meson build Nipun Gupta
2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-05-03 15:51         ` [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-05-03 15:52         ` [dpdk-dev] [PATCH v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-05-03 15:58         ` [dpdk-dev] [PATCH v7 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-05-03 16:06       ` [dpdk-dev] [PATCH RESEND " Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 1/8] raw: support meson build Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 2/8] bus/fslmc: support MC DPDMAI object Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 3/8] bus/fslmc: support scanning and probing of QDMA devices Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 4/8] bus/fslmc: add macros required by QDMA for FLE and FD Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 6/8] raw/dpaa2_qdma: support configuration APIs Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 7/8] raw/dpaa2_qdma: support enq and deq operations Nipun Gupta
2018-05-03 16:06         ` [dpdk-dev] [PATCH RESEND v7 8/8] doc: add DPAA2 QDMA rawdev guide Nipun Gupta
2018-05-08 10:17           ` Thomas Monjalon
2018-05-08 10:22         ` [dpdk-dev] [PATCH RESEND v7 0/8] Introduce DPAA2 QDMA raw driver Thomas Monjalon

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