[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