raw/dpaa2_cmdif: support enqueue/dequeue operations
authorNipun Gupta <nipun.gupta@nxp.com>
Fri, 4 May 2018 10:11:28 +0000 (15:41 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 8 May 2018 12:21:07 +0000 (14:21 +0200)
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
doc/api/doxy-api-index.md
doc/api/doxy-api.conf
drivers/raw/dpaa2_cmdif/Makefile
drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c
drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h
drivers/raw/dpaa2_cmdif/meson.build
drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif.h [new file with mode: 0644]

index dd57f55..55d075c 100644 (file)
@@ -39,6 +39,7 @@ The public API headers are grouped by topics:
   [bnxt]               (@ref rte_pmd_bnxt.h),
   [dpaa]               (@ref rte_pmd_dpaa.h),
   [dpaa2_mempool]      (@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)
 
index 71fb6b2..aa66751 100644 (file)
@@ -38,6 +38,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           drivers/net/i40e \
                           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 \
index 5f9b8bf..9b863dd 100644 (file)
@@ -31,4 +31,6 @@ LIBABIVER := 1
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif.c
 
+SYMLINK-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV)-include += rte_pmd_dpaa2_cmdif.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
index 093bffe..095a34b 100644 (file)
@@ -18,6 +18,7 @@
 #include <portal/dpaa2_hw_pvt.h>
 #include <portal/dpaa2_hw_dpio.h>
 #include "dpaa2_cmdif_logs.h"
+#include "rte_pmd_dpaa2_cmdif.h"
 
 /* Dynamic log type identifier */
 int dpaa2_cmdif_logtype;
@@ -52,8 +53,144 @@ dpaa2_cmdif_get_attr(struct rte_rawdev *dev,
        return 0;
 }
 
+static int
+dpaa2_cmdif_enqueue_bufs(struct rte_rawdev *dev,
+                        struct rte_rawdev_buf **buffers,
+                        unsigned int count,
+                        rte_rawdev_obj_t context)
+{
+       struct dpaa2_dpci_dev *cidev = dev->dev_private;
+       struct rte_dpaa2_cmdif_context *cmdif_send_cnxt;
+       struct dpaa2_queue *txq;
+       struct qbman_fd fd;
+       struct qbman_eq_desc eqdesc;
+       struct qbman_swp *swp;
+       int ret;
+
+       DPAA2_CMDIF_FUNC_TRACE();
+
+       RTE_SET_USED(count);
+
+       if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+               ret = dpaa2_affine_qbman_swp();
+               if (ret) {
+                       DPAA2_CMDIF_ERR("Failure in affining portal\n");
+                       return 0;
+               }
+       }
+       swp = DPAA2_PER_LCORE_PORTAL;
+
+       cmdif_send_cnxt = (struct rte_dpaa2_cmdif_context *)(context);
+       txq = &(cidev->tx_queue[cmdif_send_cnxt->priority]);
+
+       /* 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);
+
+       /* Set some of the FD parameters to i.
+        * For performance reasons do not memset
+        */
+       fd.simple.bpid_offset = 0;
+       fd.simple.ctrl = 0;
+
+       DPAA2_SET_FD_ADDR(&fd, DPAA2_VADDR_TO_IOVA(buffers[0]->buf_addr));
+       DPAA2_SET_FD_LEN(&fd, cmdif_send_cnxt->size);
+       DPAA2_SET_FD_FRC(&fd, cmdif_send_cnxt->frc);
+       DPAA2_SET_FD_FLC(&fd, cmdif_send_cnxt->flc);
+
+       /* Enqueue a packet to the QBMAN */
+       do {
+               ret = qbman_swp_enqueue_multiple(swp, &eqdesc, &fd, NULL, 1);
+               if (ret < 0 && ret != -EBUSY)
+                       DPAA2_CMDIF_ERR("Transmit failure with err: %d\n", ret);
+       } while (ret == -EBUSY);
+
+       DPAA2_CMDIF_DP_DEBUG("Successfully transmitted a packet\n");
+
+       return 0;
+}
+
+static int
+dpaa2_cmdif_dequeue_bufs(struct rte_rawdev *dev,
+                        struct rte_rawdev_buf **buffers,
+                        unsigned int count,
+                        rte_rawdev_obj_t context)
+{
+       struct dpaa2_dpci_dev *cidev = dev->dev_private;
+       struct rte_dpaa2_cmdif_context *cmdif_rcv_cnxt;
+       struct dpaa2_queue *rxq;
+       struct qbman_swp *swp;
+       struct qbman_result *dq_storage;
+       const struct qbman_fd *fd;
+       struct qbman_pull_desc pulldesc;
+       uint8_t status;
+       int ret;
+
+       DPAA2_CMDIF_FUNC_TRACE();
+
+       RTE_SET_USED(count);
+
+       if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
+               ret = dpaa2_affine_qbman_swp();
+               if (ret) {
+                       DPAA2_CMDIF_ERR("Failure in affining portal\n");
+                       return 0;
+               }
+       }
+       swp = DPAA2_PER_LCORE_PORTAL;
+
+       cmdif_rcv_cnxt = (struct rte_dpaa2_cmdif_context *)(context);
+       rxq = &(cidev->rx_queue[cmdif_rcv_cnxt->priority]);
+       dq_storage = rxq->q_storage->dq_storage[0];
+
+       qbman_pull_desc_clear(&pulldesc);
+       qbman_pull_desc_set_fq(&pulldesc, rxq->fqid);
+       qbman_pull_desc_set_numframes(&pulldesc, 1);
+       qbman_pull_desc_set_storage(&pulldesc, dq_storage,
+               (uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1);
+
+       while (1) {
+               if (qbman_swp_pull(swp, &pulldesc)) {
+                       DPAA2_CMDIF_DP_WARN("VDQ cmd not issued. QBMAN is busy\n");
+                       /* Portal was busy, try again */
+                       continue;
+               }
+               break;
+       }
+
+       /* Check if previous issued command is completed. */
+       while (!qbman_check_command_complete(dq_storage))
+               ;
+       /* Loop until the dq_storage is updated with new token by QBMAN */
+       while (!qbman_result_has_new_result(swp, dq_storage))
+               ;
+
+       /* Check for valid frame. */
+       status = (uint8_t)qbman_result_DQ_flags(dq_storage);
+       if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) {
+               DPAA2_CMDIF_DP_DEBUG("No frame is delivered\n");
+               return 0;
+       }
+
+       fd = qbman_result_DQ_fd(dq_storage);
+
+       buffers[0]->buf_addr = (void *)DPAA2_IOVA_TO_VADDR(
+                       DPAA2_GET_FD_ADDR(fd) + DPAA2_GET_FD_OFFSET(fd));
+       cmdif_rcv_cnxt->size = DPAA2_GET_FD_LEN(fd);
+       cmdif_rcv_cnxt->flc = DPAA2_GET_FD_FLC(fd);
+       cmdif_rcv_cnxt->frc = DPAA2_GET_FD_FRC(fd);
+
+       DPAA2_CMDIF_DP_DEBUG("packet received\n");
+
+       return 1;
+}
+
 static const struct rte_rawdev_ops dpaa2_cmdif_ops = {
        .attr_get = dpaa2_cmdif_get_attr,
+       .enqueue_bufs = dpaa2_cmdif_enqueue_bufs,
+       .dequeue_bufs = dpaa2_cmdif_dequeue_bufs,
 };
 
 static int
index 5eb0885..598a621 100644 (file)
@@ -9,18 +9,18 @@
 extern "C" {
 #endif
 
-#include <rte_rawdev.h>
-
 extern int dpaa2_cmdif_logtype;
 
 #define DPAA2_CMDIF_LOG(level, fmt, args...) \
-       rte_log(RTE_LOG_ ## level, dpaa2_cmdif_logtype, "%s(): " fmt "\n", \
-               __func__, ##args)
+       rte_log(RTE_LOG_ ## level, dpaa2_cmdif_logtype, "dpaa2_cmdif: " \
+               fmt "\n", ## args)
+
+#define DPAA2_CMDIF_DEBUG(fmt, args...) \
+       rte_log(RTE_LOG_DEBUG, dpaa2_cmdif_logtype, "dpaa2_cmdif: %s(): " \
+               fmt "\n", __func__, ## args)
 
 #define DPAA2_CMDIF_FUNC_TRACE() DPAA2_CMDIF_LOG(DEBUG, ">>")
 
-#define DPAA2_CMDIF_DEBUG(fmt, args...) \
-       DPAA2_CMDIF_LOG(DEBUG, fmt, ## args)
 #define DPAA2_CMDIF_INFO(fmt, args...) \
        DPAA2_CMDIF_LOG(INFO, fmt, ## args)
 #define DPAA2_CMDIF_ERR(fmt, args...) \
@@ -28,6 +28,17 @@ extern int dpaa2_cmdif_logtype;
 #define DPAA2_CMDIF_WARN(fmt, args...) \
        DPAA2_CMDIF_LOG(WARNING, fmt, ## args)
 
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_CMDIF_DP_LOG(level, fmt, args...) \
+       RTE_LOG_DP(level, PMD, "dpaa2_cmdif: " fmt "\n", ## args)
+
+#define DPAA2_CMDIF_DP_DEBUG(fmt, args...) \
+       DPAA2_CMDIF_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_CMDIF_DP_INFO(fmt, args...) \
+       DPAA2_CMDIF_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_CMDIF_DP_WARN(fmt, args...) \
+       DPAA2_CMDIF_DP_LOG(WARNING, fmt, ## args)
+
 #ifdef __cplusplus
 }
 #endif
index 91a77ce..8c90943 100644 (file)
@@ -5,3 +5,5 @@ deps += ['rawdev', 'mempool_dpaa2', 'bus_vdev']
 sources = files('dpaa2_cmdif.c')
 
 allow_experimental_apis = true
+
+install_headers('rte_pmd_dpaa2_cmdif.h')
diff --git a/drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif.h b/drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif.h
new file mode 100644 (file)
index 0000000..483b66e
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __RTE_PMD_DPAA2_CMDIF_H__
+#define __RTE_PMD_DPAA2_CMDIF_H__
+
+/**
+ * @file
+ *
+ * NXP dpaa2 AIOP CMDIF PMD specific structures.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The context required in the I/O path for DPAA2 AIOP Command Interface */
+struct rte_dpaa2_cmdif_context {
+       /** Size to populate in QBMAN FD */
+       uint32_t size;
+       /** FRC to populate in QBMAN FD */
+       uint32_t frc;
+       /** FLC to populate in QBMAN FD */
+       uint64_t flc;
+       /** Priority of the command. This priority determines DPCI Queue*/
+       uint8_t priority;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RTE_PMD_DPAA2_CMDIF_H__ */