[for-next v4 2/2] RDMA/ionic: Add RCQ userspace support
From: Abhijit Gangurde <abhijit.gangurde@amd.com>
Date: 2026-07-21 12:11:16
Also in:
linux-rdma, lkml
Subsystem:
amd pensando rdma driver, infiniband subsystem, the rest · Maintainers:
Abhijit Gangurde, Allen Hubbe, Jason Gunthorpe, Leon Romanovsky, Linus Torvalds
Expose the Reorder Completion Queue (RCQ) capability to userspace via ucontext response and allow userspace to specify ionic specific QP flags during QP creation. Co-developed-by: Allen Hubbe <allen.hubbe@amd.com> Signed-off-by: Allen Hubbe <allen.hubbe@amd.com> Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com> --- .../infiniband/hw/ionic/ionic_controlpath.c | 19 ++++++++++++++++--- drivers/infiniband/hw/ionic/ionic_fw.h | 2 ++ drivers/infiniband/hw/ionic/ionic_lif_cfg.c | 1 + drivers/infiniband/hw/ionic/ionic_lif_cfg.h | 1 + include/uapi/rdma/ionic-abi.h | 5 ++++- 5 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 9d91f7667d4f..d28f26c58927 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c@@ -408,6 +408,7 @@ int ionic_alloc_ucontext(struct ib_ucontext *ibctx, struct ib_udata *udata) resp.udma_count = dev->lif_cfg.udma_count; resp.expdb_mask = dev->lif_cfg.expdb_mask; + resp.rcq_sign_bit = dev->lif_cfg.rcq_sign_bit; if (dev->lif_cfg.sq_expdb) resp.expdb_qtypes |= IONIC_EXPDB_SQ;
@@ -1324,7 +1325,8 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev, struct ionic_qp *qp, struct ionic_tbl_buf *sq_buf, struct ionic_tbl_buf *rq_buf, - struct ib_qp_init_attr *attr) + struct ib_qp_init_attr *attr, + u32 ionic_flags) { const u16 dbid = ionic_obj_dbid(dev, pd->ibpd.uobject); const u32 flags = to_ionic_qp_flags(0, 0,
@@ -1340,7 +1342,12 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev, .len = cpu_to_le16(IONIC_ADMIN_CREATE_QP_IN_V1_LEN), .cmd.create_qp = { .pd_id = cpu_to_le32(pd->pdid), - .priv_flags = cpu_to_be32(flags), + /* User-supplied ionic_flags are passed through to + * firmware, which validates and rejects any + * unsupported or unauthorized bits. + */ + .priv_flags = cpu_to_be32(flags | + (ionic_flags & IONIC_QP_USER_FLAGS_MASK)), .type_state = to_ionic_qp_type(attr->qp_type), .dbid_flags = cpu_to_le16(dbid), .id_ver = cpu_to_le32(qp->qpid),
@@ -2157,6 +2164,12 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr, rc = ib_copy_validate_udata_in(udata, req, rsvd); if (rc) return rc; + + if (req.ionic_flags & ~IONIC_QP_USER_FLAGS_MASK) + return -EINVAL; + + if (req.rsvd_pad) + return -EINVAL; } else { req.sq_spec = IONIC_SPEC_HIGH; req.rq_spec = IONIC_SPEC_HIGH;
@@ -2237,7 +2250,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr, rc = ionic_create_qp_cmd(dev, pd, to_ionic_vcq_cq(attr->send_cq, qp->udma_idx), to_ionic_vcq_cq(attr->recv_cq, qp->udma_idx), - qp, &sq_buf, &rq_buf, attr); + qp, &sq_buf, &rq_buf, attr, req.ionic_flags); if (rc) goto err_cmd;
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index adfbb89d856c..4c6752bfb1de 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h@@ -105,6 +105,8 @@ enum ionic_qp_flags { IONIC_QPF_SQ_CMB = BIT(13), IONIC_QPF_RQ_CMB = BIT(14), IONIC_QPF_PRIVILEGED = BIT(15), + + IONIC_QP_USER_FLAGS_MASK = GENMASK(31, 16), }; static inline int from_ionic_qp_flags(int flags)
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
index f3cd281c3a2f..a9044f47c913 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c@@ -84,6 +84,7 @@ void ionic_fill_lif_cfg(struct ionic_lif *lif, struct ionic_lif_cfg *cfg) cfg->udma_count = 2; cfg->max_stride = ident->rdma.max_stride; + cfg->rcq_sign_bit = ident->rdma.rcq_sign_bit; cfg->expdb_mask = ionic_get_expdb(lif); cfg->sq_expdb =
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
index 20853429f623..e6b17055147f 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h@@ -56,6 +56,7 @@ struct ionic_lif_cfg { bool sq_expdb; bool rq_expdb; u8 expdb_mask; + u8 rcq_sign_bit; }; void ionic_fill_lif_cfg(struct ionic_lif *lif, struct ionic_lif_cfg *cfg);
diff --git a/include/uapi/rdma/ionic-abi.h b/include/uapi/rdma/ionic-abi.h
index 7b589d3e9728..b1ec59efb49c 100644
--- a/include/uapi/rdma/ionic-abi.h
+++ b/include/uapi/rdma/ionic-abi.h@@ -46,8 +46,9 @@ struct ionic_ctx_resp { __u8 udma_count; __u8 expdb_mask; __u8 expdb_qtypes; + __u8 rcq_sign_bit; - __u8 rsvd2[3]; + __u8 rsvd2[2]; }; struct ionic_qdesc {
@@ -84,6 +85,8 @@ struct ionic_qp_req { __u8 rq_cmb; __u8 udma_mask; __u8 rsvd[3]; + __u32 ionic_flags; + __u32 rsvd_pad; }; struct ionic_qp_resp {
--
2.43.0