[PATCH v1 1/2] dma/odm: support dev to mem transfers

Shijith Thotton sthotton at marvell.com
Mon Jun 1 12:15:58 CEST 2026


From: Vamsi Attunuru <vattunuru at marvell.com>

Adds support for dev to mem and mem to dev
DMA transfers.

Signed-off-by: Vamsi Attunuru <vattunuru at marvell.com>
Signed-off-by: Shijith Thotton <sthotton at marvell.com>
---
 drivers/dma/odm/odm.c        | 51 ++++++++++++++++++++++++++++++++++--
 drivers/dma/odm/odm.h        | 12 ++++++++-
 drivers/dma/odm/odm_dmadev.c |  9 ++++---
 drivers/dma/odm/odm_priv.h   |  4 ++-
 4 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/odm/odm.c b/drivers/dma/odm/odm.c
index 270808f4df..0633ce0b4b 100644
--- a/drivers/dma/odm/odm.c
+++ b/drivers/dma/odm/odm.c
@@ -125,13 +125,41 @@ odm_disable(struct odm_dev *odm)
 	return 0;
 }
 
+static int
+odm_get_ext_port_type(const struct rte_dma_vchan_conf *conf, uint8_t *ext_port)
+{
+	uint8_t coreid;
+
+	if (conf->src_port.port_type == RTE_DMA_PORT_PCIE) {
+		coreid = conf->src_port.pcie.coreid;
+	} else if (conf->dst_port.port_type == RTE_DMA_PORT_PCIE) {
+		coreid = conf->dst_port.pcie.coreid;
+	} else {
+		*ext_port = ODM_EXT_PORT_NCB;
+		return 0;
+	}
+
+	switch (coreid) {
+	case 0:
+		*ext_port = ODM_EXT_PORT_PEM0;
+		return 0;
+	case 1:
+		*ext_port = ODM_EXT_PORT_PEM1;
+		return 0;
+	default:
+		ODM_LOG(ERR, "Unsupported PCIe coreid %u (only 0 and 1 are valid)", coreid);
+		return -EINVAL;
+	}
+}
+
 int
-odm_vchan_setup(struct odm_dev *odm, int vchan, int nb_desc)
+odm_vchan_setup(struct odm_dev *odm, int vchan, const struct rte_dma_vchan_conf *conf)
 {
 	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;
+	uint8_t ext_port;
 	char name[32];
 
 	if (vq->iring_mz != NULL)
@@ -140,10 +168,29 @@ odm_vchan_setup(struct odm_dev *odm, int vchan, int nb_desc)
 	mbox_msg.u[0] = 0;
 	mbox_msg.u[1] = 0;
 
+	switch (conf->direction) {
+	case RTE_DMA_DIR_DEV_TO_MEM:
+		vq->xtype = ODM_XTYPE_INBOUND;
+		break;
+	case RTE_DMA_DIR_MEM_TO_DEV:
+		vq->xtype = ODM_XTYPE_OUTBOUND;
+		break;
+	case RTE_DMA_DIR_MEM_TO_MEM:
+		vq->xtype = ODM_XTYPE_INTERNAL;
+		break;
+	default:
+		ODM_LOG(ERR, "Unsupported DMA direction %d", conf->direction);
+		return -EINVAL;
+	}
+
 	/* 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 = odm_get_ext_port_type(conf, &ext_port);
+	if (rc < 0)
+		return rc;
+	mbox_msg.q.ext_port = ext_port;
 	rc = send_mbox_to_pf(odm, &mbox_msg, &mbox_msg);
 	if (rc < 0)
 		return rc;
@@ -151,7 +198,7 @@ odm_vchan_setup(struct odm_dev *odm, int vchan, int nb_desc)
 	/* 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_ALIGN_CEIL(conf->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, SOCKET_ID_ANY, 0, 1024);
diff --git a/drivers/dma/odm/odm.h b/drivers/dma/odm/odm.h
index 6b96439094..a6b06daeb2 100644
--- a/drivers/dma/odm/odm.h
+++ b/drivers/dma/odm/odm.h
@@ -9,6 +9,7 @@
 
 #include <rte_common.h>
 #include <rte_compat.h>
+#include <rte_dmadev.h>
 #include <rte_io.h>
 #include <rte_log.h>
 #include <rte_memzone.h>
@@ -40,10 +41,17 @@
  * ODM Transfer Type Enumeration
  * Enumerates the pointer type in ODM_DMA_INSTR_HDR_S[XTYPE]
  */
+#define ODM_XTYPE_OUTBOUND 0
+#define ODM_XTYPE_INBOUND  1
 #define ODM_XTYPE_INTERNAL 2
 #define ODM_XTYPE_FILL0	   4
 #define ODM_XTYPE_FILL1	   5
 
+/* ODM external port type */
+#define ODM_EXT_PORT_PEM0 0x0
+#define ODM_EXT_PORT_PEM1 0x1
+#define ODM_EXT_PORT_NCB  0x2
+
 /*
  *  ODM Header completion type enumeration
  *  Enumerates the completion type in ODM_DMA_INSTR_HDR_S[CT]
@@ -168,6 +176,8 @@ struct odm_queue {
 	uint16_t iring_max_words;
 	/* Number of words in cring.*/
 	uint16_t cring_max_entry;
+	/* DMA transfer type.*/
+	uint16_t xtype;
 	/* Extra instruction size used per inflight instruction.*/
 	uint8_t *extra_ins_sz;
 	struct vq_stats stats;
@@ -189,6 +199,6 @@ 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);
+int odm_vchan_setup(struct odm_dev *odm, int vchan, const struct rte_dma_vchan_conf *conf);
 
 #endif /* _ODM_H_ */
diff --git a/drivers/dma/odm/odm_dmadev.c b/drivers/dma/odm/odm_dmadev.c
index a2f4ed9a8e..0211133bd4 100644
--- a/drivers/dma/odm/odm_dmadev.c
+++ b/drivers/dma/odm/odm_dmadev.c
@@ -30,7 +30,8 @@ odm_dmadev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info *dev_info
 	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);
+		(RTE_DMA_CAPA_MEM_TO_MEM | RTE_DMA_CAPA_OPS_COPY | RTE_DMA_CAPA_OPS_COPY_SG |
+		 RTE_DMA_CAPA_MEM_TO_DEV | RTE_DMA_CAPA_DEV_TO_MEM);
 	dev_info->max_desc = ODM_IRING_MAX_ENTRY;
 	dev_info->min_desc = 1;
 	dev_info->max_sges = ODM_MAX_POINTER;
@@ -58,7 +59,7 @@ odm_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
 	struct odm_dev *odm = dev->fp_obj->dev_private;
 
 	RTE_SET_USED(conf_sz);
-	return odm_vchan_setup(odm, vchan, conf->nb_desc);
+	return odm_vchan_setup(odm, vchan, conf);
 }
 
 static int
@@ -99,7 +100,7 @@ odm_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t ds
 	struct odm_queue *vq;
 	uint64_t h;
 
-	const union odm_instr_hdr_s hdr = {
+	union odm_instr_hdr_s hdr = {
 		.s.ct = ODM_HDR_CT_CW_NC,
 		.s.xtype = ODM_XTYPE_INTERNAL,
 		.s.nfst = 1,
@@ -107,6 +108,7 @@ odm_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, rte_iova_t ds
 	};
 
 	vq = &odm->vq[vchan];
+	hdr.s.xtype = vq->xtype;
 
 	h = length;
 	h |= ((uint64_t)length << 32);
@@ -252,6 +254,7 @@ odm_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct rte_dma_sge *
 	vq = &odm->vq[vchan];
 	const uint16_t max_iring_words = vq->iring_max_words;
 
+	hdr.s.xtype = vq->xtype;
 	iring_head_ptr = vq->iring_mz->addr;
 	iring_head = vq->iring_head;
 	iring_sz_available = vq->iring_sz_available;
diff --git a/drivers/dma/odm/odm_priv.h b/drivers/dma/odm/odm_priv.h
index 1878f4d9a6..71a46c7122 100644
--- a/drivers/dma/odm/odm_priv.h
+++ b/drivers/dma/odm/odm_priv.h
@@ -34,8 +34,10 @@ struct odm_mbox_queue_msg {
 	uint64_t vfid : 8;
 	/* Queue index in the VF */
 	uint64_t qidx : 8;
+	/* Port type for external DMA access */
+	uint64_t ext_port : 8;
 	/* Reserved */
-	uint64_t rsvd_24_63 : 40;
+	uint64_t rsvd_32_63 : 32;
 };
 
 union odm_mbox_msg {
-- 
2.25.1



More information about the dev mailing list