All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anoob Joseph <anoobj@marvell.com>
To: Chengwen Feng <fengchengwen@huawei.com>,
	Kevin Laatz <kevin.laatz@intel.com>,
	Bruce Richardson <bruce.richardson@intel.com>,
	"Jerin Jacob" <jerinj@marvell.com>,
	Thomas Monjalon <thomas@monjalon.net>
Cc: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>,
	"Vidya Sagar Velumuri" <vvelumuri@marvell.com>, <dev@dpdk.org>
Subject: [PATCH v2 4/7] dma/odm: add device ops
Date: Wed, 17 Apr 2024 12:57:05 +0530	[thread overview]
Message-ID: <20240417072708.322-5-anoobj@marvell.com> (raw)
In-Reply-To: <20240417072708.322-1-anoobj@marvell.com>

From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>

Add DMA device control ops.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
---
 drivers/dma/odm/odm.c        | 144 ++++++++++++++++++++++++++++++++++-
 drivers/dma/odm/odm.h        |  58 ++++++++++++++
 drivers/dma/odm/odm_dmadev.c |  85 +++++++++++++++++++++
 3 files changed, 285 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/odm/odm.c b/drivers/dma/odm/odm.c
index c0963da451..6094ace9fd 100644
--- a/drivers/dma/odm/odm.c
+++ b/drivers/dma/odm/odm.c
@@ -7,6 +7,7 @@
 #include <bus_pci_driver.h>
 
 #include <rte_io.h>
+#include <rte_malloc.h>
 
 #include "odm.h"
 #include "odm_priv.h"
@@ -14,8 +15,15 @@
 static void
 odm_vchan_resc_free(struct odm_dev *odm, int qno)
 {
-	RTE_SET_USED(odm);
-	RTE_SET_USED(qno);
+	struct odm_queue *vq = &odm->vq[qno];
+
+	rte_memzone_free(vq->iring_mz);
+	rte_memzone_free(vq->cring_mz);
+	rte_free(vq->extra_ins_sz);
+
+	vq->iring_mz = NULL;
+	vq->cring_mz = NULL;
+	vq->extra_ins_sz = NULL;
 }
 
 static int
@@ -53,6 +61,138 @@ send_mbox_to_pf(struct odm_dev *odm, union odm_mbox_msg *msg, union odm_mbox_msg
 	return 0;
 }
 
+static int
+odm_queue_ring_config(struct odm_dev *odm, int vchan, int isize, int csize)
+{
+	union odm_vdma_ring_cfg_s ring_cfg = {0};
+	struct odm_queue *vq = &odm->vq[vchan];
+
+	if (vq->iring_mz == NULL || vq->cring_mz == NULL)
+		return -EINVAL;
+
+	ring_cfg.s.isize = (isize / 1024) - 1;
+	ring_cfg.s.csize = (csize / 1024) - 1;
+
+	odm_write64(ring_cfg.u, odm->rbase + ODM_VDMA_RING_CFG(vchan));
+	odm_write64(vq->iring_mz->iova, odm->rbase + ODM_VDMA_IRING_BADDR(vchan));
+	odm_write64(vq->cring_mz->iova, odm->rbase + ODM_VDMA_CRING_BADDR(vchan));
+
+	return 0;
+}
+
+int
+odm_enable(struct odm_dev *odm)
+{
+	struct odm_queue *vq;
+	int qno, rc = 0;
+
+	for (qno = 0; qno < odm->num_qs; qno++) {
+		vq = &odm->vq[qno];
+
+		vq->desc_idx = vq->stats.completed_offset;
+		vq->pending_submit_len = 0;
+		vq->pending_submit_cnt = 0;
+		vq->iring_head = 0;
+		vq->cring_head = 0;
+		vq->ins_ring_head = 0;
+		vq->iring_sz_available = vq->iring_max_words;
+
+		rc = odm_queue_ring_config(odm, qno, vq->iring_max_words * 8,
+					   vq->cring_max_entry * 4);
+		if (rc < 0)
+			break;
+
+		odm_write64(0x1, odm->rbase + ODM_VDMA_EN(qno));
+	}
+
+	return rc;
+}
+
+int
+odm_disable(struct odm_dev *odm)
+{
+	int qno, wait_cnt = ODM_IRING_IDLE_WAIT_CNT;
+	uint64_t val;
+
+	/* Disable the queue and wait for the queue to became idle */
+	for (qno = 0; qno < odm->num_qs; qno++) {
+		odm_write64(0x0, odm->rbase + ODM_VDMA_EN(qno));
+		do {
+			val = odm_read64(odm->rbase + ODM_VDMA_IRING_BADDR(qno));
+		} while ((!(val & 1ULL << 63)) && (--wait_cnt > 0));
+	}
+
+	return 0;
+}
+
+int
+odm_vchan_setup(struct odm_dev *odm, int vchan, int nb_desc)
+{
+	struct odm_queue *vq = &odm->vq[vchan];
+	int isize, csize, max_nb_desc, rc = 0;
+	union odm_mbox_msg mbox_msg;
+	const struct rte_memzone *mz;
+	char name[32];
+
+	if (vq->iring_mz != NULL)
+		odm_vchan_resc_free(odm, vchan);
+
+	mbox_msg.u[0] = 0;
+	mbox_msg.u[1] = 0;
+
+	/* ODM PF driver expects vfid starts from index 0 */
+	mbox_msg.q.vfid = odm->vfid;
+	mbox_msg.q.cmd = ODM_QUEUE_OPEN;
+	mbox_msg.q.qidx = vchan;
+	rc = send_mbox_to_pf(odm, &mbox_msg, &mbox_msg);
+	if (rc < 0)
+		return rc;
+
+	/* Determine instruction & completion ring sizes. */
+
+	/* Create iring that can support nb_desc. Round up to a multiple of 1024. */
+	isize = RTE_ALIGN_CEIL(nb_desc * ODM_IRING_ENTRY_SIZE_MAX * 8, 1024);
+	isize = RTE_MIN(isize, ODM_IRING_MAX_SIZE);
+	snprintf(name, sizeof(name), "vq%d_iring%d", odm->vfid, vchan);
+	mz = rte_memzone_reserve_aligned(name, isize, 0, ODM_MEMZONE_FLAGS, 1024);
+	if (mz == NULL)
+		return -ENOMEM;
+	vq->iring_mz = mz;
+	vq->iring_max_words = isize / 8;
+
+	/* Create cring that can support max instructions that can be inflight in hw. */
+	max_nb_desc = (isize / (ODM_IRING_ENTRY_SIZE_MIN * 8));
+	csize = RTE_ALIGN_CEIL(max_nb_desc * sizeof(union odm_cmpl_ent_s), 1024);
+	snprintf(name, sizeof(name), "vq%d_cring%d", odm->vfid, vchan);
+	mz = rte_memzone_reserve_aligned(name, csize, 0, ODM_MEMZONE_FLAGS, 1024);
+	if (mz == NULL) {
+		rc = -ENOMEM;
+		goto iring_free;
+	}
+	vq->cring_mz = mz;
+	vq->cring_max_entry = csize / 4;
+
+	/* Allocate memory to track the size of each instruction. */
+	snprintf(name, sizeof(name), "vq%d_extra%d", odm->vfid, vchan);
+	vq->extra_ins_sz = rte_zmalloc(name, vq->cring_max_entry, 0);
+	if (vq->extra_ins_sz == NULL) {
+		rc = -ENOMEM;
+		goto cring_free;
+	}
+
+	vq->stats = (struct vq_stats){0};
+	return rc;
+
+cring_free:
+	rte_memzone_free(odm->vq[vchan].cring_mz);
+	vq->cring_mz = NULL;
+iring_free:
+	rte_memzone_free(odm->vq[vchan].iring_mz);
+	vq->iring_mz = NULL;
+
+	return rc;
+}
+
 int
 odm_dev_init(struct odm_dev *odm)
 {
diff --git a/drivers/dma/odm/odm.h b/drivers/dma/odm/odm.h
index 9fd3e30ad8..e1373e0c7f 100644
--- a/drivers/dma/odm/odm.h
+++ b/drivers/dma/odm/odm.h
@@ -9,7 +9,9 @@
 
 #include <rte_common.h>
 #include <rte_compat.h>
+#include <rte_io.h>
 #include <rte_log.h>
+#include <rte_memzone.h>
 
 extern int odm_logtype;
 
@@ -54,6 +56,14 @@ extern int odm_logtype;
 
 #define ODM_MAX_QUEUES_PER_DEV 16
 
+#define ODM_IRING_MAX_SIZE	 (256 * 1024)
+#define ODM_IRING_ENTRY_SIZE_MIN 4
+#define ODM_IRING_ENTRY_SIZE_MAX 13
+#define ODM_IRING_MAX_WORDS	 (ODM_IRING_MAX_SIZE / 8)
+#define ODM_IRING_MAX_ENTRY	 (ODM_IRING_MAX_WORDS / ODM_IRING_ENTRY_SIZE_MIN)
+
+#define ODM_MAX_POINTER 4
+
 #define odm_read64(addr)       rte_read64_relaxed((volatile void *)(addr))
 #define odm_write64(val, addr) rte_write64_relaxed((val), (volatile void *)(addr))
 
@@ -66,6 +76,10 @@ extern int odm_logtype;
 		RTE_FMT("%s(): %u" RTE_FMT_HEAD(__VA_ARGS__, ), __func__, __LINE__,                \
 			RTE_FMT_TAIL(__VA_ARGS__, )))
 
+#define ODM_MEMZONE_FLAGS                                                                          \
+	(RTE_MEMZONE_1GB | RTE_MEMZONE_16MB | RTE_MEMZONE_16GB | RTE_MEMZONE_256MB |               \
+	 RTE_MEMZONE_512MB | RTE_MEMZONE_4GB | RTE_MEMZONE_SIZE_HINT_ONLY)
+
 /**
  * Structure odm_instr_hdr_s for ODM
  *
@@ -141,8 +155,48 @@ union odm_vdma_counts_s {
 	} s;
 };
 
+struct vq_stats {
+	uint64_t submitted;
+	uint64_t completed;
+	uint64_t errors;
+	/*
+	 * Since stats.completed is used to return completion index, account for any packets
+	 * received before stats is reset.
+	 */
+	uint64_t completed_offset;
+};
+
+struct odm_queue {
+	struct odm_dev *dev;
+	/* Instructions that are prepared on the iring, but is not pushed to hw yet. */
+	uint16_t pending_submit_cnt;
+	/* Length (in words) of instructions that are not yet pushed to hw. */
+	uint16_t pending_submit_len;
+	uint16_t desc_idx;
+	/* Instruction ring head. Used for enqueue. */
+	uint16_t iring_head;
+	/* Completion ring head. Used for dequeue. */
+	uint16_t cring_head;
+	/* Extra instruction size ring head. Used in enqueue-dequeue.*/
+	uint16_t ins_ring_head;
+	/* Extra instruction size ring tail. Used in enqueue-dequeue.*/
+	uint16_t ins_ring_tail;
+	/* Instruction size available.*/
+	uint16_t iring_sz_available;
+	/* Number of 8-byte words in iring.*/
+	uint16_t iring_max_words;
+	/* Number of words in cring.*/
+	uint16_t cring_max_entry;
+	/* Extra instruction size used per inflight instruction.*/
+	uint8_t *extra_ins_sz;
+	struct vq_stats stats;
+	const struct rte_memzone *iring_mz;
+	const struct rte_memzone *cring_mz;
+};
+
 struct __rte_cache_aligned odm_dev {
 	struct rte_pci_device *pci_dev;
+	struct odm_queue vq[ODM_MAX_QUEUES_PER_DEV];
 	uint8_t *rbase;
 	uint16_t vfid;
 	uint8_t max_qs;
@@ -151,5 +205,9 @@ struct __rte_cache_aligned odm_dev {
 
 int odm_dev_init(struct odm_dev *odm);
 int odm_dev_fini(struct odm_dev *odm);
+int odm_configure(struct odm_dev *odm);
+int odm_enable(struct odm_dev *odm);
+int odm_disable(struct odm_dev *odm);
+int odm_vchan_setup(struct odm_dev *odm, int vchan, int nb_desc);
 
 #endif /* _ODM_H_ */
diff --git a/drivers/dma/odm/odm_dmadev.c b/drivers/dma/odm/odm_dmadev.c
index bef335c10c..8c705978fe 100644
--- a/drivers/dma/odm/odm_dmadev.c
+++ b/drivers/dma/odm/odm_dmadev.c
@@ -17,6 +17,87 @@
 #define PCI_DEVID_ODYSSEY_ODM_VF 0xA08C
 #define PCI_DRIVER_NAME		 dma_odm
 
+static int
+odm_dmadev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info *dev_info, uint32_t size)
+{
+	struct odm_dev *odm = NULL;
+
+	RTE_SET_USED(size);
+
+	odm = dev->fp_obj->dev_private;
+
+	dev_info->max_vchans = odm->max_qs;
+	dev_info->nb_vchans = odm->num_qs;
+	dev_info->dev_capa =
+		(RTE_DMA_CAPA_MEM_TO_MEM | RTE_DMA_CAPA_OPS_COPY | RTE_DMA_CAPA_OPS_COPY_SG);
+	dev_info->max_desc = ODM_IRING_MAX_ENTRY;
+	dev_info->min_desc = 1;
+	dev_info->max_sges = ODM_MAX_POINTER;
+
+	return 0;
+}
+
+static int
+odm_dmadev_configure(struct rte_dma_dev *dev, const struct rte_dma_conf *conf, uint32_t conf_sz)
+{
+	struct odm_dev *odm = NULL;
+
+	RTE_SET_USED(conf_sz);
+
+	odm = dev->fp_obj->dev_private;
+	odm->num_qs = conf->nb_vchans;
+
+	return 0;
+}
+
+static int
+odm_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
+		       const struct rte_dma_vchan_conf *conf, uint32_t conf_sz)
+{
+	struct odm_dev *odm = dev->fp_obj->dev_private;
+
+	RTE_SET_USED(conf_sz);
+	return odm_vchan_setup(odm, vchan, conf->nb_desc);
+}
+
+static int
+odm_dmadev_start(struct rte_dma_dev *dev)
+{
+	struct odm_dev *odm = dev->fp_obj->dev_private;
+
+	return odm_enable(odm);
+}
+
+static int
+odm_dmadev_stop(struct rte_dma_dev *dev)
+{
+	struct odm_dev *odm = dev->fp_obj->dev_private;
+
+	return odm_disable(odm);
+}
+
+static int
+odm_dmadev_close(struct rte_dma_dev *dev)
+{
+	struct odm_dev *odm = dev->fp_obj->dev_private;
+
+	odm_disable(odm);
+	odm_dev_fini(odm);
+
+	return 0;
+}
+
+static const struct rte_dma_dev_ops odm_dmadev_ops = {
+	.dev_close = odm_dmadev_close,
+	.dev_configure = odm_dmadev_configure,
+	.dev_info_get = odm_dmadev_info_get,
+	.dev_start = odm_dmadev_start,
+	.dev_stop = odm_dmadev_stop,
+	.stats_get = NULL,
+	.stats_reset = NULL,
+	.vchan_setup = odm_dmadev_vchan_setup,
+};
+
 static int
 odm_dmadev_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev)
 {
@@ -40,6 +121,10 @@ odm_dmadev_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_dev
 	odm_info("DMA device %s probed", name);
 	odm = dmadev->data->dev_private;
 
+	dmadev->device = &pci_dev->device;
+	dmadev->fp_obj->dev_private = odm;
+	dmadev->dev_ops = &odm_dmadev_ops;
+
 	odm->pci_dev = pci_dev;
 
 	rc = odm_dev_init(odm);
-- 
2.25.1


  parent reply	other threads:[~2024-04-17  7:28 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-15 15:31 [PATCH 0/8] Add ODM DMA device Anoob Joseph
2024-04-15 15:31 ` [PATCH 1/8] usertools/devbind: add " Anoob Joseph
2024-04-15 15:31 ` [PATCH 2/8] dma/odm: add framework for " Anoob Joseph
2024-04-15 15:31 ` [PATCH 3/8] dma/odm: add hardware defines Anoob Joseph
2024-04-15 15:31 ` [PATCH 4/8] dma/odm: add dev init and fini Anoob Joseph
2024-04-15 15:31 ` [PATCH 5/8] dma/odm: add device ops Anoob Joseph
2024-04-15 15:31 ` [PATCH 6/8] dma/odm: add stats Anoob Joseph
2024-04-15 15:31 ` [PATCH 7/8] dma/odm: add copy and copy sg ops Anoob Joseph
2024-04-15 15:31 ` [PATCH 8/8] dma/odm: add remaining ops Anoob Joseph
2024-04-17  7:27 ` [PATCH v2 0/7] Add ODM DMA device Anoob Joseph
2024-04-17  7:27   ` [PATCH v2 1/7] dma/odm: add framework for " Anoob Joseph
2024-04-17  7:27   ` [PATCH v2 2/7] dma/odm: add hardware defines Anoob Joseph
2024-04-17  7:27   ` [PATCH v2 3/7] dma/odm: add dev init and fini Anoob Joseph
2024-04-17  7:27   ` Anoob Joseph [this message]
2024-04-17  7:27   ` [PATCH v2 5/7] dma/odm: add stats Anoob Joseph
2024-04-17  7:27   ` [PATCH v2 6/7] dma/odm: add copy and copy sg ops Anoob Joseph
2024-04-17  7:27   ` [PATCH v2 7/7] dma/odm: add remaining ops Anoob Joseph
2024-04-19  6:43   ` [PATCH v3 0/7] Add ODM DMA device Anoob Joseph
2024-04-19  6:43     ` [PATCH v3 1/7] dma/odm: add framework for " Anoob Joseph
2024-05-24 13:26       ` Jerin Jacob
2024-04-19  6:43     ` [PATCH v3 2/7] dma/odm: add hardware defines Anoob Joseph
2024-05-24 13:29       ` Jerin Jacob
2024-04-19  6:43     ` [PATCH v3 3/7] dma/odm: add dev init and fini Anoob Joseph
2024-04-19  6:43     ` [PATCH v3 4/7] dma/odm: add device ops Anoob Joseph
2024-05-24 13:37       ` Jerin Jacob
2024-04-19  6:43     ` [PATCH v3 5/7] dma/odm: add stats Anoob Joseph
2024-04-19  6:43     ` [PATCH v3 6/7] dma/odm: add copy and copy sg ops Anoob Joseph
2024-04-19  6:43     ` [PATCH v3 7/7] dma/odm: add remaining ops Anoob Joseph
2024-05-27 15:16     ` [PATCH v4 0/7] Add ODM DMA device Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 1/7] dma/odm: add framework for " Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 2/7] dma/odm: add hardware defines Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 3/7] dma/odm: add dev init and fini Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 4/7] dma/odm: add device ops Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 5/7] dma/odm: add stats Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 6/7] dma/odm: add copy and copy sg ops Anoob Joseph
2024-05-27 15:16       ` [PATCH v4 7/7] dma/odm: add remaining ops Anoob Joseph
2024-05-28  8:12       ` [PATCH v4 0/7] Add ODM DMA device Jerin Jacob

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240417072708.322-5-anoobj@marvell.com \
    --to=anoobj@marvell.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=fengchengwen@huawei.com \
    --cc=gmuthukrishn@marvell.com \
    --cc=jerinj@marvell.com \
    --cc=kevin.laatz@intel.com \
    --cc=thomas@monjalon.net \
    --cc=vvelumuri@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.