* [PATCH 1/1] RDMA/ionic: Preserve and set Ethernet source MAC after ib_ud_header_init()
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: Reserve bytes in CQE format for future use Abhijit Gangurde
` (14 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde, stable
ionic_build_hdr() populated the Ethernet source MAC (hdr->eth.smac_h) by
passing the header’s storage directly to rdma_read_gid_l2_fields().
However, ib_ud_header_init() is called after that and re-initializes the
UD header, which wipes the previously written smac_h. As a result, packets
are emitted with an zero source MAC address on the wire.
Correct the source MAC by reading the GID-derived smac into a temporary
buffer and copy it after ib_ud_header_init() completes.
Fixes: e8521822c733 ("RDMA/ionic: Register device ops for control path")
Cc: stable@vger.kernel.org # 6.18
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/infiniband/hw/ionic/ionic_controlpath.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index ea12d9b8e125..84bc5f17a700 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -508,6 +508,7 @@ static int ionic_build_hdr(struct ionic_ibdev *dev,
{
const struct ib_global_route *grh;
enum rdma_network_type net;
+ u8 smac[ETH_ALEN];
u16 vlan;
int rc;
@@ -518,7 +519,7 @@ static int ionic_build_hdr(struct ionic_ibdev *dev,
grh = rdma_ah_read_grh(attr);
- rc = rdma_read_gid_l2_fields(grh->sgid_attr, &vlan, &hdr->eth.smac_h[0]);
+ rc = rdma_read_gid_l2_fields(grh->sgid_attr, &vlan, smac);
if (rc)
return rc;
@@ -536,6 +537,7 @@ static int ionic_build_hdr(struct ionic_ibdev *dev,
if (rc)
return rc;
+ ether_addr_copy(hdr->eth.smac_h, smac);
ether_addr_copy(hdr->eth.dmac_h, attr->roce.dmac);
if (net == RDMA_NETWORK_IPV4) {
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 1/1] RDMA/ionic: Reserve bytes in CQE format for future use
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: Preserve and set Ethernet source MAC after ib_ud_header_init() Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: map PHC state into user space Abhijit Gangurde
` (13 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
Reserve a few bytes from wqe_id in the CQE format for future use.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/infiniband/hw/ionic/ionic_datapath.c | 42 +++++++++++---------
drivers/infiniband/hw/ionic/ionic_fw.h | 11 +++--
2 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
index aa2944887f23..518de4c7757d 100644
--- a/drivers/infiniband/hw/ionic/ionic_datapath.c
+++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
@@ -32,6 +32,7 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
{
struct ionic_rq_meta *meta;
struct ionic_v1_wqe *wqe;
+ u64 wqe_idx;
if (!qp->rq_flush)
return 0;
@@ -40,21 +41,22 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
return 0;
wqe = ionic_queue_at_cons(&qp->rq);
+ wqe_idx = le64_to_cpu(wqe->base.wqe_idx);
- /* wqe_id must be a valid queue index */
- if (unlikely(wqe->base.wqe_id >> qp->rq.depth_log2)) {
+ /* wqe_idx must be a valid queue index */
+ if (unlikely(wqe_idx >> qp->rq.depth_log2)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[wqe->base.wqe_id];
+ /* wqe_idx must indicate a request that is outstanding */
+ meta = &qp->rq_meta[wqe_idx];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
@@ -133,8 +135,8 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
{
struct ionic_qp *qp = NULL;
struct ionic_rq_meta *meta;
+ u16 vlan_tag, wqe_idx;
u32 src_qpn, st_len;
- u16 vlan_tag;
u8 op;
if (cqe_qp->rq_flush)
@@ -144,7 +146,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
st_len = be32_to_cpu(cqe->status_length);
- /* ignore wqe_id in case of flush error */
+ /* ignore wqe_idx in case of flush error */
if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) {
cqe_qp->rq_flush = true;
cq->flush = true;
@@ -160,20 +162,22 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
return -EIO;
}
- /* wqe_id must be a valid queue index */
- if (unlikely(cqe->recv.wqe_id >> qp->rq.depth_log2)) {
+ wqe_idx = le64_to_cpu(cqe->recv.wqe_idx) & IONIC_V1_CQE_WQE_IDX_MASK;
+
+ /* wqe_idx must be a valid queue index */
+ if (unlikely(wqe_idx >> qp->rq.depth_log2)) {
ibdev_warn(&dev->ibdev,
"qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[cqe->recv.wqe_id];
+ /* wqe_idx must indicate a request that is outstanding */
+ meta = &qp->rq_meta[wqe_idx];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(&dev->ibdev,
"qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
@@ -408,7 +412,7 @@ static int ionic_comp_msn(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
{
struct ionic_sq_meta *meta;
- u16 cqe_idx;
+ u16 wqe_idx;
u32 st_len;
if (qp->sq_flush)
@@ -430,8 +434,8 @@ static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
return 0;
}
- cqe_idx = cqe->send.npg_wqe_id & qp->sq.mask;
- meta = &qp->sq_meta[cqe_idx];
+ wqe_idx = le64_to_cpu(cqe->send.npg_wqe_idx) & qp->sq.mask;
+ meta = &qp->sq_meta[wqe_idx];
meta->local_comp = true;
if (ionic_v1_cqe_error(cqe)) {
@@ -811,7 +815,7 @@ static void ionic_prep_base(struct ionic_qp *qp,
meta->signal = false;
meta->local_comp = false;
- wqe->base.wqe_id = qp->sq.prod;
+ wqe->base.wqe_idx = cpu_to_le64(qp->sq.prod);
if (wr->send_flags & IB_SEND_FENCE)
wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_FENCE);
@@ -1205,7 +1209,7 @@ static int ionic_prep_recv(struct ionic_qp *qp,
meta->wrid = wr->wr_id;
- wqe->base.wqe_id = meta - qp->rq_meta;
+ wqe->base.wqe_idx = cpu_to_le64(meta - qp->rq_meta);
wqe->base.num_sge_key = wr->num_sge;
/* total length for recv goes in base imm_data_key */
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index adfbb89d856c..64ab897bf194 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h
@@ -332,7 +332,7 @@ struct ionic_v1_cqe {
__le16 old_rq_cq_cindex;
} admin;
struct {
- __u64 wqe_id;
+ __le64 wqe_idx;
__be32 src_qpn_op;
__u8 src_mac[6];
__be16 vlan_tag;
@@ -342,13 +342,18 @@ struct ionic_v1_cqe {
__u8 rsvd[4];
__be32 msg_msn;
__u8 rsvd2[8];
- __u64 npg_wqe_id;
+ __le64 npg_wqe_idx;
} send;
};
__be32 status_length;
__be32 qid_type_flags;
};
+/* bits for cqe wqe_idx */
+enum ionic_v1_cqe_wqe_idx_bits {
+ IONIC_V1_CQE_WQE_IDX_MASK = 0xffff,
+};
+
/* bits for cqe recv */
enum ionic_v1_cqe_src_qpn_bits {
IONIC_V1_CQE_RECV_QPN_MASK = 0xffffff,
@@ -423,7 +428,7 @@ static inline u32 ionic_v1_cqe_qtf_qid(u32 qtf)
/* v1 base wqe header */
struct ionic_v1_base_hdr {
- __u64 wqe_id;
+ __le64 wqe_idx;
__u8 op;
__u8 num_sge_key;
__be16 flags;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 1/1] RDMA/ionic: map PHC state into user space
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: Preserve and set Ethernet source MAC after ib_ud_header_init() Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: Reserve bytes in CQE format for future use Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: simplify rq_meta allocation Abhijit Gangurde
` (12 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde,
Allen Hubbe
Enable user space applications to access the PHC state page when
firmware RDMA completion timestamp is supported.
This mapping allows user space to convert RDMA completion timestamps
to system wall time without kernel transitions, minimizing latency
overhead. Applications can directly read the PHC state through mmap,
enabling efficient timestamp correlation for precision timing
applications.
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 | 36 +++++++++++++++-
drivers/infiniband/hw/ionic/ionic_datapath.c | 43 ++++++++++---------
drivers/infiniband/hw/ionic/ionic_fw.h | 12 ++++--
drivers/infiniband/hw/ionic/ionic_ibdev.h | 2 +
drivers/infiniband/hw/ionic/ionic_lif_cfg.c | 2 +
drivers/infiniband/hw/ionic/ionic_lif_cfg.h | 1 +
include/uapi/rdma/ionic-abi.h | 1 +
7 files changed, 72 insertions(+), 25 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index ea12d9b8e125..c04e02d41535 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -391,6 +391,16 @@ int ionic_alloc_ucontext(struct ib_ucontext *ibctx, struct ib_udata *udata)
goto err_mmap_dbell;
}
+ if (dev->lif_cfg.phc_state) {
+ ctx->mmap_phc = ionic_mmap_entry_insert(ctx, PAGE_SIZE, 0,
+ IONIC_MMAP_PHC,
+ &resp.phc_offset);
+ if (!ctx->mmap_phc) {
+ rc = -ENOMEM;
+ goto err_mmap_phc;
+ }
+ }
+
resp.page_shift = PAGE_SHIFT;
resp.dbell_offset = db_phys & ~PAGE_MASK;
@@ -414,13 +424,15 @@ int ionic_alloc_ucontext(struct ib_ucontext *ibctx, struct ib_udata *udata)
if (dev->lif_cfg.rq_expdb)
resp.expdb_qtypes |= IONIC_EXPDB_RQ;
- rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
+ rc = ib_copy_to_udata(udata, &resp, min(sizeof(resp), udata->outlen));
if (rc)
goto err_resp;
return 0;
err_resp:
+ rdma_user_mmap_entry_remove(ctx->mmap_phc);
+err_mmap_phc:
rdma_user_mmap_entry_remove(ctx->mmap_dbell);
err_mmap_dbell:
ionic_put_dbid(dev, ctx->dbid);
@@ -433,10 +445,26 @@ void ionic_dealloc_ucontext(struct ib_ucontext *ibctx)
struct ionic_ibdev *dev = to_ionic_ibdev(ibctx->device);
struct ionic_ctx *ctx = to_ionic_ctx(ibctx);
+ rdma_user_mmap_entry_remove(ctx->mmap_phc);
rdma_user_mmap_entry_remove(ctx->mmap_dbell);
ionic_put_dbid(dev, ctx->dbid);
}
+static int ionic_mmap_phc_stage(struct ionic_ibdev *dev,
+ struct vm_area_struct *vma)
+{
+ if (!(vma->vm_flags & VM_SHARED))
+ return -EINVAL;
+
+ if (vma->vm_flags & (VM_WRITE | VM_EXEC))
+ return -EPERM;
+
+ vm_flags_clear(vma, VM_MAYWRITE);
+
+ return vm_insert_page(vma, vma->vm_start,
+ virt_to_page(dev->lif_cfg.phc_state));
+}
+
int ionic_mmap(struct ib_ucontext *ibctx, struct vm_area_struct *vma)
{
struct ionic_ibdev *dev = to_ionic_ibdev(ibctx->device);
@@ -455,6 +483,12 @@ int ionic_mmap(struct ib_ucontext *ibctx, struct vm_area_struct *vma)
ionic_entry = container_of(rdma_entry, struct ionic_mmap_entry,
rdma_entry);
+ if (ionic_entry->mmap_flags & IONIC_MMAP_PHC) {
+ rc = ionic_mmap_phc_stage(dev, vma);
+ rdma_user_mmap_entry_put(rdma_entry);
+ return rc;
+ }
+
ibdev_dbg(&dev->ibdev, "writecombine? %d\n",
ionic_entry->mmap_flags & IONIC_MMAP_WC);
if (ionic_entry->mmap_flags & IONIC_MMAP_WC)
diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
index aa2944887f23..3e2300f7ea10 100644
--- a/drivers/infiniband/hw/ionic/ionic_datapath.c
+++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
@@ -32,6 +32,7 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
{
struct ionic_rq_meta *meta;
struct ionic_v1_wqe *wqe;
+ u64 wqe_idx;
if (!qp->rq_flush)
return 0;
@@ -40,21 +41,22 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
return 0;
wqe = ionic_queue_at_cons(&qp->rq);
+ wqe_idx = le64_to_cpu(wqe->base.wqe_idx);
- /* wqe_id must be a valid queue index */
- if (unlikely(wqe->base.wqe_id >> qp->rq.depth_log2)) {
+ /* wqe_idx must be a valid queue index */
+ if (unlikely(wqe_idx >> qp->rq.depth_log2)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[wqe->base.wqe_id];
+ /* wqe_idx must indicate a request that is outstanding */
+ meta = &qp->rq_meta[wqe_idx];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
+ qp->qpid, (unsigned long long)wqe_idx);
return -EIO;
}
@@ -133,8 +135,8 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
{
struct ionic_qp *qp = NULL;
struct ionic_rq_meta *meta;
+ u16 vlan_tag, wqe_idx;
u32 src_qpn, st_len;
- u16 vlan_tag;
u8 op;
if (cqe_qp->rq_flush)
@@ -144,7 +146,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
st_len = be32_to_cpu(cqe->status_length);
- /* ignore wqe_id in case of flush error */
+ /* ignore wqe_idx in case of flush error */
if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) {
cqe_qp->rq_flush = true;
cq->flush = true;
@@ -160,20 +162,19 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
return -EIO;
}
- /* wqe_id must be a valid queue index */
- if (unlikely(cqe->recv.wqe_id >> qp->rq.depth_log2)) {
+ wqe_idx = le64_to_cpu(cqe->recv.wqe_idx_timestamp) & IONIC_V1_CQE_WQE_IDX_MASK;
+ /* wqe_idx must be a valid queue index */
+ if (unlikely(wqe_idx >> qp->rq.depth_log2)) {
ibdev_warn(&dev->ibdev,
- "qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
+ "qp %u recv index %u invalid\n", qp->qpid, wqe_idx);
return -EIO;
}
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[cqe->recv.wqe_id];
+ /* wqe_idx must indicate a request that is outstanding */
+ meta = &qp->rq_meta[wqe_idx];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(&dev->ibdev,
- "qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
+ "qp %u recv index %u not posted\n", qp->qpid, wqe_idx);
return -EIO;
}
@@ -408,7 +409,7 @@ static int ionic_comp_msn(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
{
struct ionic_sq_meta *meta;
- u16 cqe_idx;
+ u16 wqe_idx;
u32 st_len;
if (qp->sq_flush)
@@ -430,8 +431,8 @@ static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
return 0;
}
- cqe_idx = cqe->send.npg_wqe_id & qp->sq.mask;
- meta = &qp->sq_meta[cqe_idx];
+ wqe_idx = le64_to_cpu(cqe->send.npg_wqe_idx_timestamp) & qp->sq.mask;
+ meta = &qp->sq_meta[wqe_idx];
meta->local_comp = true;
if (ionic_v1_cqe_error(cqe)) {
@@ -811,7 +812,7 @@ static void ionic_prep_base(struct ionic_qp *qp,
meta->signal = false;
meta->local_comp = false;
- wqe->base.wqe_id = qp->sq.prod;
+ wqe->base.wqe_idx = cpu_to_le64(qp->sq.prod);
if (wr->send_flags & IB_SEND_FENCE)
wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_FENCE);
@@ -1205,7 +1206,7 @@ static int ionic_prep_recv(struct ionic_qp *qp,
meta->wrid = wr->wr_id;
- wqe->base.wqe_id = meta - qp->rq_meta;
+ wqe->base.wqe_idx = cpu_to_le64(meta - qp->rq_meta);
wqe->base.num_sge_key = wr->num_sge;
/* total length for recv goes in base imm_data_key */
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index adfbb89d856c..ee23062a1762 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h
@@ -332,7 +332,7 @@ struct ionic_v1_cqe {
__le16 old_rq_cq_cindex;
} admin;
struct {
- __u64 wqe_id;
+ __le64 wqe_idx_timestamp;
__be32 src_qpn_op;
__u8 src_mac[6];
__be16 vlan_tag;
@@ -342,13 +342,19 @@ struct ionic_v1_cqe {
__u8 rsvd[4];
__be32 msg_msn;
__u8 rsvd2[8];
- __u64 npg_wqe_id;
+ __le64 npg_wqe_idx_timestamp;
} send;
};
__be32 status_length;
__be32 qid_type_flags;
};
+/* bits for cqe wqe_idx and timestamp */
+enum ionic_v1_cqe_wqe_idx_timestamp_bits {
+ IONIC_V1_CQE_WQE_IDX_MASK = 0xffff,
+ IONIC_V1_CQE_TIMESTAMP_SHIFT = 16,
+};
+
/* bits for cqe recv */
enum ionic_v1_cqe_src_qpn_bits {
IONIC_V1_CQE_RECV_QPN_MASK = 0xffffff,
@@ -423,7 +429,7 @@ static inline u32 ionic_v1_cqe_qtf_qid(u32 qtf)
/* v1 base wqe header */
struct ionic_v1_base_hdr {
- __u64 wqe_id;
+ __le64 wqe_idx;
__u8 op;
__u8 num_sge_key;
__be16 flags;
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.h b/drivers/infiniband/hw/ionic/ionic_ibdev.h
index 82fda1e3cdb6..de23376267f5 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.h
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.h
@@ -72,6 +72,7 @@ enum ionic_admin_flags {
enum ionic_mmap_flag {
IONIC_MMAP_WC = BIT(0),
+ IONIC_MMAP_PHC = BIT(1),
};
struct ionic_mmap_entry {
@@ -173,6 +174,7 @@ struct ionic_ctx {
struct ib_ucontext ibctx;
u32 dbid;
struct rdma_user_mmap_entry *mmap_dbell;
+ struct rdma_user_mmap_entry *mmap_phc;
};
struct ionic_tbl_buf {
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
index f3cd281c3a2f..54eaa30cce78 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
@@ -40,6 +40,8 @@ void ionic_fill_lif_cfg(struct ionic_lif *lif, struct ionic_lif_cfg *cfg)
cfg->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif);
cfg->dbpage = lif->kern_dbpage;
cfg->intr_ctrl = lif->ionic->idev.intr_ctrl;
+ if (le64_to_cpu(ident->eth.config.features) & IONIC_ETH_HW_RDMA_TIMESTAMP)
+ cfg->phc_state = lif->phc->state_page;
cfg->db_phys = lif->ionic->bars[IONIC_PCI_BAR_DBELL].bus_addr;
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
index 20853429f623..2b29e646c193 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
@@ -23,6 +23,7 @@ struct ionic_lif_cfg {
u64 __iomem *dbpage;
struct ionic_intr __iomem *intr_ctrl;
phys_addr_t db_phys;
+ void *phc_state;
u64 page_size_supported;
u32 npts_per_lif;
diff --git a/include/uapi/rdma/ionic-abi.h b/include/uapi/rdma/ionic-abi.h
index 97f695510380..abd1bde0991f 100644
--- a/include/uapi/rdma/ionic-abi.h
+++ b/include/uapi/rdma/ionic-abi.h
@@ -48,6 +48,7 @@ struct ionic_ctx_resp {
__u8 expdb_qtypes;
__u8 rsvd2[3];
+ __aligned_u64 phc_offset;
};
struct ionic_qdesc {
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 1/1] RDMA/ionic: simplify rq_meta allocation
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (2 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: map PHC state into user space Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v3 1/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (11 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
Eliminate the free rq_meta entries. Instead, maintain rq_meta
as a parallel array to rq WQEs, indexed by the WQE index.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
.../infiniband/hw/ionic/ionic_controlpath.c | 14 +---
drivers/infiniband/hw/ionic/ionic_datapath.c | 64 ++++---------------
drivers/infiniband/hw/ionic/ionic_fw.h | 11 +++-
drivers/infiniband/hw/ionic/ionic_ibdev.h | 5 --
4 files changed, 20 insertions(+), 74 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index a5045c08915e..b82513297b41 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -2008,8 +2008,8 @@ static int ionic_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
struct ionic_tbl_buf *buf, int max_wr, int max_sge,
int rq_spec, struct ib_udata *udata, int access)
{
- int rc = 0, i;
u32 wqe_size;
+ int rc = 0;
rq->cmb_prod = 0;
rc = -EINVAL;
@@ -2079,11 +2079,6 @@ static int ionic_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
rc = -ENOMEM;
goto err_rq_meta;
}
-
- for (i = 0; i < rq->q.mask; ++i)
- rq->meta[i].next = &rq->meta[i + 1];
- rq->meta[i].next = IONIC_META_LAST;
- rq->meta_head = &rq->meta[0];
}
ionic_rq_init_cmb(dev, rq, udata);
@@ -2476,7 +2471,6 @@ static void ionic_reset_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
{
unsigned long irqflags;
struct ionic_cq *cq;
- int i;
local_irq_save(irqflags);
@@ -2510,12 +2504,6 @@ static void ionic_reset_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
qp->rq.flush = false;
qp->rq.q.prod = 0;
qp->rq.q.cons = 0;
- if (qp->rq.meta) {
- for (i = 0; i < qp->rq.q.mask; ++i)
- qp->rq.meta[i].next = &qp->rq.meta[i + 1];
- qp->rq.meta[i].next = IONIC_META_LAST;
- }
- qp->rq.meta_head = &qp->rq.meta[0];
spin_unlock(&qp->rq.lock);
}
diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
index b8fa6b6e5f33..f49ec764f888 100644
--- a/drivers/infiniband/hw/ionic/ionic_datapath.c
+++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
@@ -31,7 +31,6 @@ static bool ionic_next_cqe(struct ionic_ibdev *dev, struct ionic_cq *cq,
static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
{
struct ionic_rq_meta *meta;
- struct ionic_v1_wqe *wqe;
if (!qp->rq.flush)
return 0;
@@ -39,25 +38,7 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
if (ionic_queue_empty(&qp->rq.q))
return 0;
- wqe = ionic_queue_at_cons(&qp->rq.q);
-
- /* wqe_id must be a valid queue index */
- if (unlikely(wqe->base.wqe_id >> qp->rq.q.depth_log2)) {
- ibdev_warn(qp->ibqp.device,
- "flush qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
- return -EIO;
- }
-
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq.meta[wqe->base.wqe_id];
- if (unlikely(meta->next != IONIC_META_POSTED)) {
- ibdev_warn(qp->ibqp.device,
- "flush qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)wqe->base.wqe_id);
- return -EIO;
- }
-
+ meta = &qp->rq.meta[qp->rq.q.cons];
ionic_queue_consume(&qp->rq.q);
memset(wc, 0, sizeof(*wc));
@@ -66,9 +47,6 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
wc->wr_id = meta->wrid;
wc->qp = &qp->ibqp;
- meta->next = qp->rq.meta_head;
- qp->rq.meta_head = meta;
-
return 1;
}
@@ -133,8 +111,8 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
{
struct ionic_qp *qp = NULL;
struct ionic_rq_meta *meta;
+ u16 vlan_tag, wqe_idx;
u32 src_qpn, st_len;
- u16 vlan_tag;
u8 op;
if (cqe_qp->rq.flush)
@@ -160,30 +138,17 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
return -EIO;
}
- /* wqe_id must be a valid queue index */
- if (unlikely(cqe->recv.wqe_id >> qp->rq.q.depth_log2)) {
- ibdev_warn(&dev->ibdev,
- "qp %u recv index %llu invalid\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
- return -EIO;
- }
-
- /* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq.meta[cqe->recv.wqe_id];
- if (unlikely(meta->next != IONIC_META_POSTED)) {
- ibdev_warn(&dev->ibdev,
- "qp %u recv index %llu not posted\n",
- qp->qpid, (unsigned long long)cqe->recv.wqe_id);
+ wqe_idx = le64_to_cpu(cqe->recv.wqe_id) & IONIC_V1_CQE_WQE_IDX_MASK;
+ if (unlikely(wqe_idx != qp->rq.q.cons)) {
+ ibdev_warn(&dev->ibdev, "wqe not next to complete %#x cons %#x prod %#x",
+ wqe_idx, qp->rq.q.cons, qp->rq.q.prod);
return -EIO;
}
- meta->next = qp->rq.meta_head;
- qp->rq.meta_head = meta;
-
+ meta = &qp->rq.meta[wqe_idx];
memset(wc, 0, sizeof(*wc));
wc->wr_id = meta->wrid;
-
wc->qp = &cqe_qp->ibqp;
if (ionic_v1_cqe_error(cqe)) {
@@ -430,7 +395,7 @@ static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe)
return 0;
}
- cqe_idx = cqe->send.npg_wqe_id & qp->sq.mask;
+ cqe_idx = le64_to_cpu(cqe->send.npg_wqe_id) & qp->sq.mask;
meta = &qp->sq_meta[cqe_idx];
meta->local_comp = true;
@@ -811,7 +776,7 @@ static void ionic_prep_base(struct ionic_qp *qp,
meta->signal = false;
meta->local_comp = false;
- wqe->base.wqe_id = qp->sq.prod;
+ wqe->base.wqe_id = cpu_to_le64(qp->sq.prod);
if (wr->send_flags & IB_SEND_FENCE)
wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_FENCE);
@@ -1188,11 +1153,7 @@ static int ionic_prep_recv(struct ionic_qp *qp,
if (wqe->base.flags & cpu_to_be16(IONIC_V1_FLAG_FENCE))
return -EAGAIN;
- meta = qp->rq.meta_head;
- if (unlikely(meta == IONIC_META_LAST) ||
- unlikely(meta == IONIC_META_POSTED))
- return -EIO;
-
+ meta = &qp->rq.meta[qp->rq.q.prod];
ionic_prep_rq_wqe(qp, wqe);
mval = ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2, qp->rq.spec,
@@ -1205,7 +1166,7 @@ static int ionic_prep_recv(struct ionic_qp *qp,
meta->wrid = wr->wr_id;
- wqe->base.wqe_id = meta - qp->rq.meta;
+ wqe->base.wqe_id = cpu_to_le64(meta - qp->rq.meta);
wqe->base.num_sge_key = wr->num_sge;
/* total length for recv goes in base imm_data_key */
@@ -1213,9 +1174,6 @@ static int ionic_prep_recv(struct ionic_qp *qp,
ionic_queue_produce(&qp->rq.q);
- qp->rq.meta_head = meta->next;
- meta->next = IONIC_META_POSTED;
-
return 0;
}
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index adfbb89d856c..8c0b456e2443 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h
@@ -332,7 +332,7 @@ struct ionic_v1_cqe {
__le16 old_rq_cq_cindex;
} admin;
struct {
- __u64 wqe_id;
+ __le64 wqe_id;
__be32 src_qpn_op;
__u8 src_mac[6];
__be16 vlan_tag;
@@ -342,13 +342,18 @@ struct ionic_v1_cqe {
__u8 rsvd[4];
__be32 msg_msn;
__u8 rsvd2[8];
- __u64 npg_wqe_id;
+ __le64 npg_wqe_id;
} send;
};
__be32 status_length;
__be32 qid_type_flags;
};
+/* bits for cqe wqe_idx */
+enum ionic_v1_cqe_wqe_id_bits {
+ IONIC_V1_CQE_WQE_IDX_MASK = 0xffff,
+};
+
/* bits for cqe recv */
enum ionic_v1_cqe_src_qpn_bits {
IONIC_V1_CQE_RECV_QPN_MASK = 0xffffff,
@@ -423,7 +428,7 @@ static inline u32 ionic_v1_cqe_qtf_qid(u32 qtf)
/* v1 base wqe header */
struct ionic_v1_base_hdr {
- __u64 wqe_id;
+ __le64 wqe_id;
__u8 op;
__u8 num_sge_key;
__be16 flags;
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.h b/drivers/infiniband/hw/ionic/ionic_ibdev.h
index 872ce4872084..09fea709e45b 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.h
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.h
@@ -37,9 +37,6 @@
#define IONIC_SQCMB_ORDER 5
#define IONIC_RQCMB_ORDER 0
-#define IONIC_META_LAST ((void *)1ul)
-#define IONIC_META_POSTED ((void *)2ul)
-
#define IONIC_CQ_GRACE 100
#define IONIC_ROCE_UDP_SPORT 28272
@@ -236,7 +233,6 @@ struct ionic_sq_meta {
};
struct ionic_rq_meta {
- struct ionic_rq_meta *next;
u64 wrid;
};
@@ -252,7 +248,6 @@ struct ionic_rq {
struct rdma_user_mmap_entry *mmap_cmb;
struct ionic_rq_meta *meta;
- struct ionic_rq_meta *meta_head;
struct ib_umem *umem;
int spec;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v3 1/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (3 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 1/1] RDMA/ionic: simplify rq_meta allocation Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 1/4] net: ionic: update LIF identity for RDMA SRQ capability Abhijit Gangurde
` (10 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde,
Nikhil Agarwal
Register shutdown callback for cdx controller platform device
to handle graceful connection closure of rpmsg transport.
Reviewed-by: Nikhil Agarwal <Nikhil.agarwal@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
Changes v2->v3:
- Rebased on v7.2-rc1
- Dropped patch 2/2 from v2 (already merged as 6d2478a103a8)
Changes v1->v2:
- Split single patch into two
drivers/cdx/controller/cdx_controller.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c
index 280bb7490c0f..2295b8bfe87e 100644
--- a/drivers/cdx/controller/cdx_controller.c
+++ b/drivers/cdx/controller/cdx_controller.c
@@ -234,6 +234,11 @@ static void xlnx_cdx_remove(struct platform_device *pdev)
kfree(cdx_mcdi);
}
+static void xlnx_cdx_shutdown(struct platform_device *pdev)
+{
+ cdx_destroy_rpmsg(pdev);
+}
+
static const struct of_device_id cdx_match_table[] = {
{.compatible = "xlnx,versal-net-cdx",},
{ },
@@ -248,6 +253,7 @@ static struct platform_driver cdx_pdriver = {
},
.probe = xlnx_cdx_probe,
.remove = xlnx_cdx_remove,
+ .shutdown = xlnx_cdx_shutdown,
};
module_platform_driver(cdx_pdriver);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 1/4] net: ionic: update LIF identity for RDMA SRQ capability
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (4 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v3 1/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 2/4] RDMA/ionic: segregate rq related fields from ionic_qp into a new ionic_rq struct Abhijit Gangurde
` (9 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
Update the LIF indentity for additional RDMA SRQ support used by
RDMA driver.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/net/ethernet/pensando/ionic/ionic_if.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 47559c909c8b..dfcf89512dca 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -553,6 +553,8 @@ enum ionic_lif_rdma_cap_stats {
* @rdma.eq_qtype: RDMA Event Qtype
* @rdma.stats_type: Supported statistics type
* (enum ionic_lif_rdma_cap_stats)
+ * @rdma.rsvd: Reserved bytes
+ * @rdma.srq_qtype: RDMA Shared Receive Qtype
* @rdma.rsvd1: Reserved byte(s)
* @words: word access to struct contents
*/
@@ -598,7 +600,9 @@ union ionic_lif_identity {
struct ionic_lif_logical_qtype cq_qtype;
struct ionic_lif_logical_qtype eq_qtype;
__le16 stats_type;
- u8 rsvd1[162];
+ u8 rsvd[2];
+ struct ionic_lif_logical_qtype srq_qtype;
+ u8 rsvd1[148];
} __packed rdma;
} __packed;
__le32 words[478];
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 2/4] RDMA/ionic: segregate rq related fields from ionic_qp into a new ionic_rq struct
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (5 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 1/4] net: ionic: update LIF identity for RDMA SRQ capability Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 3/4] RDMA/ionic: add Shared receive queue (SRQ) support Abhijit Gangurde
` (8 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
In preparation for SRQ support, segregate rq related fields from ionic_qp
into a new ionic_rq struct so that it can leverage the code in and around
ionic_qp_rq_init/_destroy. ionic_rq would enable both non-srq and srq
code to use the same rq init/destroy infra.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
.../infiniband/hw/ionic/ionic_controlpath.c | 306 +++++++++---------
drivers/infiniband/hw/ionic/ionic_datapath.c | 80 ++---
drivers/infiniband/hw/ionic/ionic_ibdev.h | 42 ++-
3 files changed, 220 insertions(+), 208 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index ea12d9b8e125..a5045c08915e 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -1327,8 +1327,8 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev,
const u16 dbid = ionic_obj_dbid(dev, pd->ibpd.uobject);
const u32 flags = to_ionic_qp_flags(0, 0,
qp->sq_cmb & IONIC_CMB_ENABLE,
- qp->rq_cmb & IONIC_CMB_ENABLE,
- qp->sq_spec, qp->rq_spec,
+ qp->rq.cmb & IONIC_CMB_ENABLE,
+ qp->sq_spec, qp->rq.spec,
pd->flags & IONIC_QPF_PRIVILEGED,
pd_remote_privileged(&pd->ibpd));
struct ionic_admin_wr wr = {
@@ -1362,8 +1362,8 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev,
if (qp->has_rq) {
wr.wqe.cmd.create_qp.rq_cq_id = cpu_to_le32(recv_cq->cqid);
- wr.wqe.cmd.create_qp.rq_depth_log2 = qp->rq.depth_log2;
- wr.wqe.cmd.create_qp.rq_stride_log2 = qp->rq.stride_log2;
+ wr.wqe.cmd.create_qp.rq_depth_log2 = qp->rq.q.depth_log2;
+ wr.wqe.cmd.create_qp.rq_stride_log2 = qp->rq.q.stride_log2;
wr.wqe.cmd.create_qp.rq_page_size_log2 = rq_buf->page_size_log2;
wr.wqe.cmd.create_qp.rq_tbl_index_srq_id = cpu_to_le32(~0);
wr.wqe.cmd.create_qp.rq_map_count =
@@ -1385,8 +1385,8 @@ static int ionic_modify_qp_cmd(struct ionic_ibdev *dev,
const u32 flags = to_ionic_qp_flags(attr->qp_access_flags,
attr->en_sqd_async_notify,
qp->sq_cmb & IONIC_CMB_ENABLE,
- qp->rq_cmb & IONIC_CMB_ENABLE,
- qp->sq_spec, qp->rq_spec,
+ qp->rq.cmb & IONIC_CMB_ENABLE,
+ qp->sq_spec, qp->rq.spec,
pd->flags & IONIC_QPF_PRIVILEGED,
pd_remote_privileged(qp->ibqp.pd));
const u8 state = to_ionic_qp_modify_state(attr->qp_state,
@@ -1556,9 +1556,9 @@ static int ionic_query_qp_cmd(struct ionic_ibdev *dev,
if (qp->has_rq) {
attr->cap.max_recv_sge =
- ionic_v1_recv_wqe_max_sge(qp->rq.stride_log2,
- qp->rq_spec,
- qp->rq_cmb & IONIC_CMB_EXPDB);
+ ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2,
+ qp->rq.spec,
+ qp->rq.cmb & IONIC_CMB_EXPDB);
}
query_sqbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
@@ -1930,99 +1930,88 @@ static void ionic_qp_sq_destroy(struct ionic_ibdev *dev,
ionic_queue_destroy(&qp->sq, dev->lif_cfg.hwdev);
}
-static void ionic_qp_rq_init_cmb(struct ionic_ibdev *dev,
- struct ionic_qp *qp,
- struct ib_udata *udata)
+static void ionic_rq_init_cmb(struct ionic_ibdev *dev,
+ struct ionic_rq *rq,
+ struct ib_udata *udata)
{
u8 expdb_stride_log2 = 0;
bool expdb;
int rc;
- if (!(qp->rq_cmb & IONIC_CMB_ENABLE))
+ if (!(rq->cmb & IONIC_CMB_ENABLE))
goto not_in_cmb;
- if (qp->rq_cmb & ~IONIC_CMB_SUPPORTED) {
- if (qp->rq_cmb & IONIC_CMB_REQUIRE)
+ if (rq->cmb & ~IONIC_CMB_SUPPORTED) {
+ if (rq->cmb & IONIC_CMB_REQUIRE)
goto not_in_cmb;
- qp->rq_cmb &= IONIC_CMB_SUPPORTED;
+ rq->cmb &= IONIC_CMB_SUPPORTED;
}
- if ((qp->rq_cmb & IONIC_CMB_EXPDB) && !dev->lif_cfg.rq_expdb) {
- if (qp->rq_cmb & IONIC_CMB_REQUIRE)
+ if ((rq->cmb & IONIC_CMB_EXPDB) && !dev->lif_cfg.rq_expdb) {
+ if (rq->cmb & IONIC_CMB_REQUIRE)
goto not_in_cmb;
- qp->rq_cmb &= ~IONIC_CMB_EXPDB;
+ rq->cmb &= ~IONIC_CMB_EXPDB;
}
- qp->rq_cmb_order = order_base_2(qp->rq.size / PAGE_SIZE);
+ rq->cmb_order = order_base_2(rq->q.size / PAGE_SIZE);
- if (qp->rq_cmb_order >= IONIC_RQCMB_ORDER)
+ if (rq->cmb_order >= IONIC_RQCMB_ORDER)
goto not_in_cmb;
- if (qp->rq_cmb & IONIC_CMB_EXPDB)
- expdb_stride_log2 = qp->rq.stride_log2;
+ if (rq->cmb & IONIC_CMB_EXPDB)
+ expdb_stride_log2 = rq->q.stride_log2;
- rc = ionic_get_cmb(dev->lif_cfg.lif, &qp->rq_cmb_pgid,
- &qp->rq_cmb_addr, qp->rq_cmb_order,
+ rc = ionic_get_cmb(dev->lif_cfg.lif, &rq->cmb_pgid,
+ &rq->cmb_addr, rq->cmb_order,
expdb_stride_log2, &expdb);
if (rc)
goto not_in_cmb;
- if ((qp->rq_cmb & IONIC_CMB_EXPDB) && !expdb) {
- if (qp->rq_cmb & IONIC_CMB_REQUIRE)
+ if ((rq->cmb & IONIC_CMB_EXPDB) && !expdb) {
+ if (rq->cmb & IONIC_CMB_REQUIRE)
goto err_map;
- qp->rq_cmb &= ~IONIC_CMB_EXPDB;
+ rq->cmb &= ~IONIC_CMB_EXPDB;
}
return;
err_map:
- ionic_put_cmb(dev->lif_cfg.lif, qp->rq_cmb_pgid, qp->rq_cmb_order);
+ ionic_put_cmb(dev->lif_cfg.lif, rq->cmb_pgid, rq->cmb_order);
not_in_cmb:
- if (qp->rq_cmb & IONIC_CMB_REQUIRE)
+ if (rq->cmb & IONIC_CMB_REQUIRE)
ibdev_dbg(&dev->ibdev, "could not place rq in cmb as required\n");
- qp->rq_cmb = 0;
- qp->rq_cmb_order = IONIC_RES_INVALID;
- qp->rq_cmb_pgid = 0;
- qp->rq_cmb_addr = 0;
+ rq->cmb = 0;
+ rq->cmb_order = IONIC_RES_INVALID;
+ rq->cmb_pgid = 0;
+ rq->cmb_addr = 0;
}
-static void ionic_qp_rq_destroy_cmb(struct ionic_ibdev *dev,
- struct ionic_ctx *ctx,
- struct ionic_qp *qp)
+static void ionic_rq_destroy_cmb(struct ionic_ibdev *dev,
+ struct ionic_ctx *ctx,
+ struct ionic_rq *rq)
{
- if (!(qp->rq_cmb & IONIC_CMB_ENABLE))
+ if (!(rq->cmb & IONIC_CMB_ENABLE))
return;
if (ctx)
- rdma_user_mmap_entry_remove(qp->mmap_rq_cmb);
+ rdma_user_mmap_entry_remove(rq->mmap_cmb);
- ionic_put_cmb(dev->lif_cfg.lif, qp->rq_cmb_pgid, qp->rq_cmb_order);
+ ionic_put_cmb(dev->lif_cfg.lif, rq->cmb_pgid, rq->cmb_order);
}
-static int ionic_qp_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
- struct ionic_qp *qp, struct ionic_qdesc *rq,
- struct ionic_tbl_buf *buf, int max_wr, int max_sge,
- int rq_spec, struct ib_udata *udata)
+static int ionic_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
+ struct ionic_rq *rq, struct ionic_qdesc *qdesc,
+ struct ionic_tbl_buf *buf, int max_wr, int max_sge,
+ int rq_spec, struct ib_udata *udata, int access)
{
int rc = 0, i;
u32 wqe_size;
- if (!qp->has_rq) {
- if (buf) {
- buf->tbl_buf = NULL;
- buf->tbl_limit = 0;
- buf->tbl_pages = 0;
- }
- if (udata)
- rc = ionic_validate_qdesc_zero(rq);
-
- return rc;
- }
-
+ rq->cmb_prod = 0;
rc = -EINVAL;
if (max_wr < 0 || max_wr > 0xffff)
@@ -2036,107 +2025,104 @@ static int ionic_qp_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
return rc;
if (udata) {
- rc = ionic_validate_qdesc(rq);
+ rc = ionic_validate_qdesc(qdesc);
if (rc)
return rc;
- qp->rq_spec = rq_spec;
+ rq->spec = rq_spec;
- qp->rq.ptr = NULL;
- qp->rq.size = rq->size;
- qp->rq.mask = rq->mask;
- qp->rq.depth_log2 = rq->depth_log2;
- qp->rq.stride_log2 = rq->stride_log2;
+ rq->q.ptr = NULL;
+ rq->q.size = qdesc->size;
+ rq->q.mask = qdesc->mask;
+ rq->q.depth_log2 = qdesc->depth_log2;
+ rq->q.stride_log2 = qdesc->stride_log2;
- qp->rq_meta = NULL;
+ rq->meta = NULL;
- qp->rq_umem = ib_umem_get(&dev->ibdev, rq->addr, rq->size, 0);
- if (IS_ERR(qp->rq_umem))
- return PTR_ERR(qp->rq_umem);
+ rq->umem = ib_umem_get(&dev->ibdev, qdesc->addr, qdesc->size, 0);
+ if (IS_ERR(rq->umem))
+ return PTR_ERR(rq->umem);
} else {
- qp->rq_umem = NULL;
+ rq->umem = NULL;
- qp->rq_spec = ionic_v1_use_spec_sge(max_sge, rq_spec);
- if (rq_spec && !qp->rq_spec)
+ rq->spec = ionic_v1_use_spec_sge(max_sge, rq_spec);
+ if (rq_spec && !rq->spec)
ibdev_dbg(&dev->ibdev,
"init rq: max_sge %u disables spec\n",
max_sge);
- if (qp->rq_cmb & IONIC_CMB_EXPDB) {
+ if (rq->cmb & IONIC_CMB_EXPDB) {
wqe_size = ionic_v1_recv_wqe_min_size(max_sge,
- qp->rq_spec,
+ rq->spec,
true);
if (!ionic_expdb_wqe_size_supported(dev, wqe_size))
- qp->rq_cmb &= ~IONIC_CMB_EXPDB;
+ rq->cmb &= ~IONIC_CMB_EXPDB;
}
- if (!(qp->rq_cmb & IONIC_CMB_EXPDB))
+ if (!(rq->cmb & IONIC_CMB_EXPDB))
wqe_size = ionic_v1_recv_wqe_min_size(max_sge,
- qp->rq_spec,
+ rq->spec,
false);
- rc = ionic_queue_init(&qp->rq, dev->lif_cfg.hwdev,
+ rc = ionic_queue_init(&rq->q, dev->lif_cfg.hwdev,
max_wr, wqe_size);
if (rc)
return rc;
- ionic_queue_dbell_init(&qp->rq, qp->qpid);
+ ionic_queue_dbell_init(&rq->q, rq->qid);
- qp->rq_meta = kmalloc_array((u32)qp->rq.mask + 1,
- sizeof(*qp->rq_meta),
- GFP_KERNEL);
- if (!qp->rq_meta) {
+ rq->meta = kmalloc_array((u32)rq->q.mask + 1,
+ sizeof(*rq->meta),
+ GFP_KERNEL);
+ if (!rq->meta) {
rc = -ENOMEM;
goto err_rq_meta;
}
- for (i = 0; i < qp->rq.mask; ++i)
- qp->rq_meta[i].next = &qp->rq_meta[i + 1];
- qp->rq_meta[i].next = IONIC_META_LAST;
- qp->rq_meta_head = &qp->rq_meta[0];
+ for (i = 0; i < rq->q.mask; ++i)
+ rq->meta[i].next = &rq->meta[i + 1];
+ rq->meta[i].next = IONIC_META_LAST;
+ rq->meta_head = &rq->meta[0];
}
- ionic_qp_rq_init_cmb(dev, qp, udata);
+ ionic_rq_init_cmb(dev, rq, udata);
- if (qp->rq_cmb & IONIC_CMB_ENABLE)
+ if (rq->cmb & IONIC_CMB_ENABLE)
rc = ionic_pgtbl_init(dev, buf, NULL,
- (u64)qp->rq_cmb_pgid << PAGE_SHIFT,
+ (u64)rq->cmb_pgid << PAGE_SHIFT,
1, PAGE_SIZE);
else
- rc = ionic_pgtbl_init(dev, buf,
- qp->rq_umem, qp->rq.dma, 1, PAGE_SIZE);
+ rc = ionic_pgtbl_init(dev, buf, rq->umem,
+ rq->q.dma, 1, PAGE_SIZE);
if (rc)
goto err_rq_tbl;
return 0;
err_rq_tbl:
- ionic_qp_rq_destroy_cmb(dev, ctx, qp);
- kfree(qp->rq_meta);
+ ionic_rq_destroy_cmb(dev, ctx, rq);
+ kfree(rq->meta);
err_rq_meta:
- if (qp->rq_umem)
- ib_umem_release(qp->rq_umem);
+ if (rq->umem)
+ ib_umem_release(rq->umem);
else
- ionic_queue_destroy(&qp->rq, dev->lif_cfg.hwdev);
+ ionic_queue_destroy(&rq->q, dev->lif_cfg.hwdev);
return rc;
}
-static void ionic_qp_rq_destroy(struct ionic_ibdev *dev,
- struct ionic_ctx *ctx,
- struct ionic_qp *qp)
+static void ionic_rq_destroy(struct ionic_ibdev *dev,
+ struct ionic_ctx *ctx,
+ struct ionic_rq *rq)
{
- if (!qp->has_rq)
- return;
+ ionic_rq_destroy_cmb(dev, ctx, rq);
- ionic_qp_rq_destroy_cmb(dev, ctx, qp);
+ kfree(rq->meta);
- kfree(qp->rq_meta);
-
- if (qp->rq_umem)
- ib_umem_release(qp->rq_umem);
+ if (rq->umem)
+ ib_umem_release(rq->umem);
else
- ionic_queue_destroy(&qp->rq, dev->lif_cfg.hwdev);
+ ionic_queue_destroy(&rq->q, dev->lif_cfg.hwdev);
}
int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
@@ -2174,7 +2160,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
INIT_LIST_HEAD(&qp->cq_flush_rq);
spin_lock_init(&qp->sq_lock);
- spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->rq.lock);
qp->has_sq = 1;
qp->has_rq = 1;
@@ -2218,7 +2204,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
if (udata) {
if (req.rq_cmb & IONIC_CMB_ENABLE)
- qp->rq_cmb = req.rq_cmb;
+ qp->rq.cmb = req.rq_cmb;
if (req.sq_cmb & IONIC_CMB_ENABLE)
qp->sq_cmb = req.sq_cmb;
@@ -2230,11 +2216,24 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
if (rc)
goto err_sq;
- rc = ionic_qp_rq_init(dev, ctx, qp, &req.rq, &rq_buf,
- attr->cap.max_recv_wr, attr->cap.max_recv_sge,
- req.rq_spec, udata);
- if (rc)
- goto err_rq;
+ if (qp->has_rq) {
+ /* for non-srq qps, rq qid is same as qpid */
+ qp->rq.qid = qp->qpid;
+ rc = ionic_rq_init(dev, ctx, &qp->rq, &req.rq, &rq_buf,
+ attr->cap.max_recv_wr, attr->cap.max_recv_sge,
+ req.rq_spec, udata,
+ (qp->ibqp.qp_type == IB_QPT_DRIVER) ?
+ IB_ACCESS_LOCAL_WRITE : 0);
+ if (rc)
+ goto err_rq;
+ } else {
+ rq_buf.tbl_buf = NULL;
+ rq_buf.tbl_limit = 0;
+ rq_buf.tbl_pages = 0;
+
+ if (udata)
+ rc = ionic_validate_qdesc_zero(&req.rq);
+ }
rc = ionic_create_qp_cmd(dev, pd,
to_ionic_vcq_cq(attr->send_cq, qp->udma_idx),
@@ -2280,41 +2279,41 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
resp.sq_cmb = qp->sq_cmb;
}
- if (qp->rq_cmb & IONIC_CMB_ENABLE) {
+ if (qp->rq.cmb & IONIC_CMB_ENABLE) {
bool wc;
- if ((qp->rq_cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) ==
+ if ((qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) ==
(IONIC_CMB_WC | IONIC_CMB_UC)) {
ibdev_dbg(&dev->ibdev,
- "Both rq_cmb flags IONIC_CMB_WC and IONIC_CMB_UC are set, using default driver mapping\n");
- qp->rq_cmb &= ~(IONIC_CMB_WC | IONIC_CMB_UC);
+ "Both rq.cmb flags IONIC_CMB_WC and IONIC_CMB_UC are set, using default driver mapping\n");
+ qp->rq.cmb &= ~(IONIC_CMB_WC | IONIC_CMB_UC);
}
- if (qp->rq_cmb & IONIC_CMB_EXPDB)
- wc = (qp->rq_cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
+ if (qp->rq.cmb & IONIC_CMB_EXPDB)
+ wc = (qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
== IONIC_CMB_WC;
else
- wc = (qp->rq_cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
+ wc = (qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
!= IONIC_CMB_UC;
/* let userspace know the mapping */
if (wc)
- qp->rq_cmb |= IONIC_CMB_WC;
+ qp->rq.cmb |= IONIC_CMB_WC;
else
- qp->rq_cmb |= IONIC_CMB_UC;
+ qp->rq.cmb |= IONIC_CMB_UC;
- qp->mmap_rq_cmb =
+ qp->rq.mmap_cmb =
ionic_mmap_entry_insert(ctx,
- qp->rq.size,
- PHYS_PFN(qp->rq_cmb_addr),
+ qp->rq.q.size,
+ PHYS_PFN(qp->rq.cmb_addr),
wc ? IONIC_MMAP_WC : 0,
&resp.rq_cmb_offset);
- if (!qp->mmap_rq_cmb) {
+ if (!qp->rq.mmap_cmb) {
rc = -ENOMEM;
goto err_mmap_rq;
}
- resp.rq_cmb = qp->rq_cmb;
+ resp.rq_cmb = qp->rq.cmb;
}
rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
@@ -2358,19 +2357,19 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
if (qp->has_rq) {
cq = to_ionic_vcq_cq(attr->recv_cq, qp->udma_idx);
- attr->cap.max_recv_wr = qp->rq.mask;
+ attr->cap.max_recv_wr = qp->rq.q.mask;
attr->cap.max_recv_sge =
- ionic_v1_recv_wqe_max_sge(qp->rq.stride_log2,
- qp->rq_spec,
- qp->rq_cmb & IONIC_CMB_EXPDB);
- qp->rq_cqid = cq->cqid;
+ ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2,
+ qp->rq.spec,
+ qp->rq.cmb & IONIC_CMB_EXPDB);
+ qp->rq.cqid = cq->cqid;
}
return 0;
err_resp:
- if (udata && (qp->rq_cmb & IONIC_CMB_ENABLE))
- rdma_user_mmap_entry_remove(qp->mmap_rq_cmb);
+ if (udata && (qp->rq.cmb & IONIC_CMB_ENABLE))
+ rdma_user_mmap_entry_remove(qp->rq.mmap_cmb);
err_mmap_rq:
if (udata && (qp->sq_cmb & IONIC_CMB_ENABLE))
rdma_user_mmap_entry_remove(qp->mmap_sq_cmb);
@@ -2378,7 +2377,8 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
ionic_destroy_qp_cmd(dev, qp->qpid);
err_cmd:
ionic_pgtbl_unbuf(dev, &rq_buf);
- ionic_qp_rq_destroy(dev, ctx, qp);
+ if (qp->has_rq)
+ ionic_rq_destroy(dev, ctx, &qp->rq);
err_rq:
ionic_pgtbl_unbuf(dev, &sq_buf);
ionic_qp_sq_destroy(dev, ctx, qp);
@@ -2432,15 +2432,15 @@ void ionic_flush_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
if (qp->ibqp.recv_cq) {
cq = to_ionic_vcq_cq(qp->ibqp.recv_cq, qp->udma_idx);
- /* Hold the CQ lock and QP rq_lock to set up flush */
+ /* Hold the CQ lock and QP rq.lock to set up flush */
spin_lock_irqsave(&cq->lock, irqflags);
- spin_lock(&qp->rq_lock);
- qp->rq_flush = true;
- if (!ionic_queue_empty(&qp->rq)) {
+ spin_lock(&qp->rq.lock);
+ qp->rq.flush = true;
+ if (!ionic_queue_empty(&qp->rq.q)) {
cq->flush = true;
list_move_tail(&qp->cq_flush_rq, &cq->flush_rq);
}
- spin_unlock(&qp->rq_lock);
+ spin_unlock(&qp->rq.lock);
spin_unlock_irqrestore(&cq->lock, irqflags);
}
}
@@ -2506,17 +2506,17 @@ static void ionic_reset_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
}
if (qp->has_rq) {
- spin_lock(&qp->rq_lock);
- qp->rq_flush = false;
- qp->rq.prod = 0;
- qp->rq.cons = 0;
- if (qp->rq_meta) {
- for (i = 0; i < qp->rq.mask; ++i)
- qp->rq_meta[i].next = &qp->rq_meta[i + 1];
- qp->rq_meta[i].next = IONIC_META_LAST;
+ spin_lock(&qp->rq.lock);
+ qp->rq.flush = false;
+ qp->rq.q.prod = 0;
+ qp->rq.q.cons = 0;
+ if (qp->rq.meta) {
+ for (i = 0; i < qp->rq.q.mask; ++i)
+ qp->rq.meta[i].next = &qp->rq.meta[i + 1];
+ qp->rq.meta[i].next = IONIC_META_LAST;
}
- qp->rq_meta_head = &qp->rq_meta[0];
- spin_unlock(&qp->rq_lock);
+ qp->rq.meta_head = &qp->rq.meta[0];
+ spin_unlock(&qp->rq.lock);
}
local_irq_restore(irqflags);
@@ -2611,7 +2611,7 @@ int ionic_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
attr->cap.max_send_wr = qp->sq.mask;
if (qp->has_rq)
- attr->cap.max_recv_wr = qp->rq.mask;
+ attr->cap.max_recv_wr = qp->rq.q.mask;
init_attr->event_handler = ibqp->event_handler;
init_attr->qp_context = ibqp->qp_context;
@@ -2667,7 +2667,9 @@ int ionic_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
spin_unlock_irqrestore(&cq->lock, irqflags);
}
- ionic_qp_rq_destroy(dev, ctx, qp);
+ if (qp->has_rq)
+ ionic_rq_destroy(dev, ctx, &qp->rq);
+
ionic_qp_sq_destroy(dev, ctx, qp);
if (qp->has_ah) {
ionic_put_ahid(dev, qp->ahid);
diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
index aa2944887f23..b8fa6b6e5f33 100644
--- a/drivers/infiniband/hw/ionic/ionic_datapath.c
+++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
@@ -33,16 +33,16 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
struct ionic_rq_meta *meta;
struct ionic_v1_wqe *wqe;
- if (!qp->rq_flush)
+ if (!qp->rq.flush)
return 0;
- if (ionic_queue_empty(&qp->rq))
+ if (ionic_queue_empty(&qp->rq.q))
return 0;
- wqe = ionic_queue_at_cons(&qp->rq);
+ wqe = ionic_queue_at_cons(&qp->rq.q);
/* wqe_id must be a valid queue index */
- if (unlikely(wqe->base.wqe_id >> qp->rq.depth_log2)) {
+ if (unlikely(wqe->base.wqe_id >> qp->rq.q.depth_log2)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu invalid\n",
qp->qpid, (unsigned long long)wqe->base.wqe_id);
@@ -50,7 +50,7 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
}
/* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[wqe->base.wqe_id];
+ meta = &qp->rq.meta[wqe->base.wqe_id];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(qp->ibqp.device,
"flush qp %u recv index %llu not posted\n",
@@ -58,7 +58,7 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
return -EIO;
}
- ionic_queue_consume(&qp->rq);
+ ionic_queue_consume(&qp->rq.q);
memset(wc, 0, sizeof(*wc));
@@ -66,8 +66,8 @@ static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc)
wc->wr_id = meta->wrid;
wc->qp = &qp->ibqp;
- meta->next = qp->rq_meta_head;
- qp->rq_meta_head = meta;
+ meta->next = qp->rq.meta_head;
+ qp->rq.meta_head = meta;
return 1;
}
@@ -137,7 +137,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
u16 vlan_tag;
u8 op;
- if (cqe_qp->rq_flush)
+ if (cqe_qp->rq.flush)
return 0;
qp = cqe_qp;
@@ -146,7 +146,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
/* ignore wqe_id in case of flush error */
if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) {
- cqe_qp->rq_flush = true;
+ cqe_qp->rq.flush = true;
cq->flush = true;
list_move_tail(&qp->cq_flush_rq, &cq->flush_rq);
@@ -155,13 +155,13 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
}
/* there had better be something in the recv queue to complete */
- if (ionic_queue_empty(&qp->rq)) {
+ if (ionic_queue_empty(&qp->rq.q)) {
ibdev_warn(&dev->ibdev, "qp %u is empty\n", qp->qpid);
return -EIO;
}
/* wqe_id must be a valid queue index */
- if (unlikely(cqe->recv.wqe_id >> qp->rq.depth_log2)) {
+ if (unlikely(cqe->recv.wqe_id >> qp->rq.q.depth_log2)) {
ibdev_warn(&dev->ibdev,
"qp %u recv index %llu invalid\n",
qp->qpid, (unsigned long long)cqe->recv.wqe_id);
@@ -169,7 +169,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
}
/* wqe_id must indicate a request that is outstanding */
- meta = &qp->rq_meta[cqe->recv.wqe_id];
+ meta = &qp->rq.meta[cqe->recv.wqe_id];
if (unlikely(meta->next != IONIC_META_POSTED)) {
ibdev_warn(&dev->ibdev,
"qp %u recv index %llu not posted\n",
@@ -177,8 +177,8 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
return -EIO;
}
- meta->next = qp->rq_meta_head;
- qp->rq_meta_head = meta;
+ meta->next = qp->rq.meta_head;
+ qp->rq.meta_head = meta;
memset(wc, 0, sizeof(*wc));
@@ -190,7 +190,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
wc->vendor_err = st_len;
wc->status = ionic_to_ib_status(st_len);
- cqe_qp->rq_flush = true;
+ cqe_qp->rq.flush = true;
cq->flush = true;
list_move_tail(&qp->cq_flush_rq, &cq->flush_rq);
@@ -254,7 +254,7 @@ static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq,
wc->port_num = 1;
out:
- ionic_queue_consume(&qp->rq);
+ ionic_queue_consume(&qp->rq.q);
return 1;
}
@@ -525,9 +525,9 @@ static int ionic_poll_vcq_cq(struct ionic_ibdev *dev,
switch (type) {
case IONIC_V1_CQE_TYPE_RECV:
- spin_lock(&qp->rq_lock);
+ spin_lock(&qp->rq.lock);
rc = ionic_poll_recv(dev, cq, qp, cqe, wc + npolled);
- spin_unlock(&qp->rq_lock);
+ spin_unlock(&qp->rq.lock);
if (rc < 0)
goto out;
@@ -615,9 +615,9 @@ static int ionic_poll_vcq_cq(struct ionic_ibdev *dev,
if (npolled == nwc)
goto out;
- spin_lock(&qp->rq_lock);
+ spin_lock(&qp->rq.lock);
rc = ionic_flush_recv_many(qp, wc + npolled, nwc - npolled);
- spin_unlock(&qp->rq_lock);
+ spin_unlock(&qp->rq.lock);
if (rc > 0)
npolled += rc;
@@ -880,7 +880,7 @@ static void ionic_prep_sq_wqe(struct ionic_qp *qp, void *wqe)
static void ionic_prep_rq_wqe(struct ionic_qp *qp, void *wqe)
{
- memset(wqe, 0, 1u << qp->rq.stride_log2);
+ memset(wqe, 0, 1u << qp->rq.q.stride_log2);
}
static int ionic_prep_send(struct ionic_qp *qp,
@@ -1182,38 +1182,38 @@ static int ionic_prep_recv(struct ionic_qp *qp,
s64 signed_len;
u32 mval;
- wqe = ionic_queue_at_prod(&qp->rq);
+ wqe = ionic_queue_at_prod(&qp->rq.q);
/* if wqe is owned by device, caller can try posting again soon */
if (wqe->base.flags & cpu_to_be16(IONIC_V1_FLAG_FENCE))
return -EAGAIN;
- meta = qp->rq_meta_head;
+ meta = qp->rq.meta_head;
if (unlikely(meta == IONIC_META_LAST) ||
unlikely(meta == IONIC_META_POSTED))
return -EIO;
ionic_prep_rq_wqe(qp, wqe);
- mval = ionic_v1_recv_wqe_max_sge(qp->rq.stride_log2, qp->rq_spec,
+ mval = ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2, qp->rq.spec,
false);
signed_len = ionic_prep_pld(wqe, &wqe->recv.pld,
- qp->rq_spec, mval,
+ qp->rq.spec, mval,
wr->sg_list, wr->num_sge);
if (signed_len < 0)
return signed_len;
meta->wrid = wr->wr_id;
- wqe->base.wqe_id = meta - qp->rq_meta;
+ wqe->base.wqe_id = meta - qp->rq.meta;
wqe->base.num_sge_key = wr->num_sge;
/* total length for recv goes in base imm_data_key */
wqe->base.imm_data_key = cpu_to_be32(signed_len);
- ionic_queue_produce(&qp->rq);
+ ionic_queue_produce(&qp->rq.q);
- qp->rq_meta_head = meta->next;
+ qp->rq.meta_head = meta->next;
meta->next = IONIC_META_POSTED;
return 0;
@@ -1320,10 +1320,10 @@ static int ionic_post_recv_common(struct ionic_ibdev *dev,
return -EINVAL;
}
- spin_lock_irqsave(&qp->rq_lock, irqflags);
+ spin_lock_irqsave(&qp->rq.lock, irqflags);
while (wr) {
- if (ionic_queue_full(&qp->rq)) {
+ if (ionic_queue_full(&qp->rq.q)) {
ibdev_dbg(&dev->ibdev, "queue full");
rc = -ENOMEM;
goto out;
@@ -1338,32 +1338,32 @@ static int ionic_post_recv_common(struct ionic_ibdev *dev,
out:
if (!cq) {
- spin_unlock_irqrestore(&qp->rq_lock, irqflags);
+ spin_unlock_irqrestore(&qp->rq.lock, irqflags);
goto out_unlocked;
}
- spin_unlock_irqrestore(&qp->rq_lock, irqflags);
+ spin_unlock_irqrestore(&qp->rq.lock, irqflags);
spin_lock_irqsave(&cq->lock, irqflags);
- spin_lock(&qp->rq_lock);
+ spin_lock(&qp->rq.lock);
- if (likely(qp->rq.prod != qp->rq_old_prod)) {
+ if (likely(qp->rq.q.prod != qp->rq.old_prod)) {
/* ring cq doorbell just in time */
- spend = (qp->rq.prod - qp->rq_old_prod) & qp->rq.mask;
+ spend = (qp->rq.q.prod - qp->rq.old_prod) & qp->rq.q.mask;
ionic_reserve_cq(dev, cq, spend);
- qp->rq_old_prod = qp->rq.prod;
+ qp->rq.old_prod = qp->rq.q.prod;
ionic_dbell_ring(dev->lif_cfg.dbpage, dev->lif_cfg.rq_qtype,
- ionic_queue_dbell_val(&qp->rq));
+ ionic_queue_dbell_val(&qp->rq.q));
}
- if (qp->rq_flush) {
+ if (qp->rq.flush) {
notify = true;
cq->flush = true;
list_move_tail(&qp->cq_flush_rq, &cq->flush_rq);
}
- spin_unlock(&qp->rq_lock);
+ spin_unlock(&qp->rq.lock);
spin_unlock_irqrestore(&cq->lock, irqflags);
if (notify && vcq->ibcq.comp_handler)
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.h b/drivers/infiniband/hw/ionic/ionic_ibdev.h
index 82fda1e3cdb6..5517638d4ced 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.h
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.h
@@ -240,6 +240,31 @@ struct ionic_rq_meta {
u64 wrid;
};
+struct ionic_rq {
+ struct ionic_queue q;
+ u32 qid;
+ u32 cqid;
+ struct list_head cq_flush;
+ spinlock_t lock; /* for posting and polling */
+
+ phys_addr_t cmb_addr;
+ void __iomem *cmb_ptr;
+ struct rdma_user_mmap_entry *mmap_cmb;
+
+ struct ionic_rq_meta *meta;
+ struct ionic_rq_meta *meta_head;
+ u16 *meta_idx;
+ struct ib_umem *umem;
+
+ int spec;
+ int cmb_order;
+ u32 cmb_pgid;
+ u16 cmb_prod;
+ u16 old_prod;
+ u8 cmb;
+ bool flush;
+};
+
struct ionic_qp {
struct ib_qp ibqp;
enum ib_qp_state state;
@@ -247,7 +272,6 @@ struct ionic_qp {
u32 qpid;
u32 ahid;
u32 sq_cqid;
- u32 rq_cqid;
u8 udma_idx;
u8 has_ah:1;
u8 has_sq:1;
@@ -273,14 +297,7 @@ struct ionic_qp {
bool sq_flush;
bool sq_flush_rcvd;
- spinlock_t rq_lock; /* for posting and polling */
- struct ionic_queue rq;
- struct ionic_rq_meta *rq_meta;
- struct ionic_rq_meta *rq_meta_head;
- int rq_spec;
- u16 rq_old_prod;
- u8 rq_cmb;
- bool rq_flush;
+ struct ionic_rq rq;
struct kref qp_kref;
struct completion qp_rel_comp;
@@ -294,13 +311,6 @@ struct ionic_qp {
struct ib_umem *sq_umem;
- int rq_cmb_order;
- u32 rq_cmb_pgid;
- phys_addr_t rq_cmb_addr;
- struct rdma_user_mmap_entry *mmap_rq_cmb;
-
- struct ib_umem *rq_umem;
-
int dcqcn_profile;
struct ib_ud_header *hdr;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 3/4] RDMA/ionic: add Shared receive queue (SRQ) support
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (6 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 2/4] RDMA/ionic: segregate rq related fields from ionic_qp into a new ionic_rq struct Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH 4/4] RDMA/ionic: implement SRQ event handling support Abhijit Gangurde
` (7 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
Implement device supported verb APIs for shared receive queue.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
.../infiniband/hw/ionic/ionic_controlpath.c | 375 +++++++++++++++---
drivers/infiniband/hw/ionic/ionic_datapath.c | 2 +-
drivers/infiniband/hw/ionic/ionic_fw.h | 42 ++
drivers/infiniband/hw/ionic/ionic_ibdev.c | 16 +
drivers/infiniband/hw/ionic/ionic_ibdev.h | 26 +-
drivers/infiniband/hw/ionic/ionic_lif_cfg.c | 1 +
drivers/infiniband/hw/ionic/ionic_lif_cfg.h | 1 +
include/uapi/rdma/ionic-abi.h | 2 +-
8 files changed, 403 insertions(+), 62 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index a5045c08915e..35eb08dd0761 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -14,6 +14,8 @@
#define ionic_set_ecn(tos) (((tos) | 2u) & ~1u)
#define ionic_clear_ecn(tos) ((tos) & ~3u)
+#define QP_USES_SRQ(qp) ((qp)->srq)
+
static int ionic_validate_qdesc(struct ionic_qdesc *q)
{
if (!q->addr || !q->size || !q->mask ||
@@ -289,6 +291,21 @@ static int ionic_get_qpid(struct ionic_ibdev *dev, u32 *qpid,
return rc;
}
+static int ionic_get_srqid(struct ionic_ibdev *dev, u32 *srqid,
+ u8 *udma_idx, u8 udma_mask)
+{
+ if (udma_mask &&
+ !(udma_mask & dev->next_srqid_udma_idx))
+ /* flip udma idx if it doesn't coincide with udma_mask */
+ dev->next_srqid_udma_idx ^= dev->lif_cfg.udma_count - 1;
+
+ *udma_idx = dev->next_srqid_udma_idx;
+ /* update udma_idx for next srqid allocation */
+ dev->next_srqid_udma_idx ^= dev->lif_cfg.udma_count - 1;
+
+ return ionic_get_cqid(dev, srqid, *udma_idx);
+}
+
static int ionic_get_dbid(struct ionic_ibdev *dev, u32 *dbid, phys_addr_t *addr)
{
int rc, dbpage_num;
@@ -331,6 +348,11 @@ static void ionic_put_qpid(struct ionic_ibdev *dev, u32 qpid)
ionic_resid_put(&dev->inuse_qpid, bitid);
}
+static inline void ionic_put_srqid(struct ionic_ibdev *dev, u32 srqid)
+{
+ ionic_put_cqid(dev, srqid);
+}
+
static void ionic_put_dbid(struct ionic_ibdev *dev, u32 dbid)
{
ionic_resid_put(&dev->inuse_dbid, dbid);
@@ -1360,7 +1382,7 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev,
wr.wqe.cmd.create_qp.sq_dma_addr = ionic_pgtbl_dma(sq_buf, 0);
}
- if (qp->has_rq) {
+ if (!QP_USES_SRQ(qp)) {
wr.wqe.cmd.create_qp.rq_cq_id = cpu_to_le32(recv_cq->cqid);
wr.wqe.cmd.create_qp.rq_depth_log2 = qp->rq.q.depth_log2;
wr.wqe.cmd.create_qp.rq_stride_log2 = qp->rq.q.stride_log2;
@@ -1369,6 +1391,9 @@ static int ionic_create_qp_cmd(struct ionic_ibdev *dev,
wr.wqe.cmd.create_qp.rq_map_count =
cpu_to_le32(rq_buf->tbl_pages);
wr.wqe.cmd.create_qp.rq_dma_addr = ionic_pgtbl_dma(rq_buf, 0);
+ } else {
+ wr.wqe.cmd.create_qp.rq_tbl_index_srq_id = cpu_to_le32(qp->srq->rq.qid);
+ wr.wqe.cmd.create_qp.rq_cq_id = cpu_to_le32(recv_cq->cqid);
}
ionic_admin_post(dev, &wr);
@@ -1554,7 +1579,7 @@ static int ionic_query_qp_cmd(struct ionic_ibdev *dev,
ionic_v1_send_wqe_max_data(qp->sq.stride_log2, expdb);
}
- if (qp->has_rq) {
+ if (!QP_USES_SRQ(qp)) {
attr->cap.max_recv_sge =
ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2,
qp->rq.spec,
@@ -1930,6 +1955,42 @@ static void ionic_qp_sq_destroy(struct ionic_ibdev *dev,
ionic_queue_destroy(&qp->sq, dev->lif_cfg.hwdev);
}
+static void ionic_rq_mmap_cmb(struct ionic_ibdev *dev,
+ struct ionic_ctx *ctx,
+ struct ionic_rq *rq,
+ u64 *cmb_offset)
+{
+ bool wc;
+
+ /* set mapping by default to uncached for
+ * expdb (to guarantee writes order) otherwise
+ * writecombine, unless this default is
+ * overridden by userspace
+ */
+ if ((rq->cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) ==
+ (IONIC_CMB_WC | IONIC_CMB_UC)) {
+ ibdev_warn(&dev->ibdev,
+ "Both rq_cmb flags IONIC_CMB_WC and IONIC_CMB_UC set, using default driver mapping\n");
+ rq->cmb &= ~(IONIC_CMB_WC | IONIC_CMB_UC);
+ }
+
+ if (rq->cmb & IONIC_CMB_EXPDB)
+ wc = (rq->cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) == IONIC_CMB_WC;
+ else
+ wc = (rq->cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) != IONIC_CMB_UC;
+
+ /* let userspace know the mapping */
+ if (wc)
+ rq->cmb |= IONIC_CMB_WC;
+ else
+ rq->cmb |= IONIC_CMB_UC;
+
+ rq->mmap_cmb = ionic_mmap_entry_insert(ctx, rq->q.size,
+ PHYS_PFN(rq->cmb_addr),
+ wc ? IONIC_MMAP_WC : 0,
+ cmb_offset);
+}
+
static void ionic_rq_init_cmb(struct ionic_ibdev *dev,
struct ionic_rq *rq,
struct ib_udata *udata)
@@ -2163,19 +2224,26 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
spin_lock_init(&qp->rq.lock);
qp->has_sq = 1;
- qp->has_rq = 1;
+
+ if (attr->srq)
+ qp->srq = to_ionic_srq(attr->srq);
+ else
+ qp->srq = NULL;
if (attr->qp_type == IB_QPT_GSI) {
rc = ionic_get_gsi_qpid(dev, &qp->qpid);
} else {
udma_mask = BIT(dev->lif_cfg.udma_count) - 1;
- if (qp->has_sq)
+ if (attr->send_cq)
udma_mask &= to_ionic_vcq(attr->send_cq)->udma_mask;
- if (qp->has_rq)
+ if (attr->recv_cq)
udma_mask &= to_ionic_vcq(attr->recv_cq)->udma_mask;
+ if (attr->srq)
+ udma_mask &= BIT(to_ionic_srq(attr->srq)->udma_idx);
+
if (udata && req.udma_mask)
udma_mask &= req.udma_mask;
@@ -2202,13 +2270,8 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
goto err_ahid;
}
- if (udata) {
- if (req.rq_cmb & IONIC_CMB_ENABLE)
- qp->rq.cmb = req.rq_cmb;
-
- if (req.sq_cmb & IONIC_CMB_ENABLE)
- qp->sq_cmb = req.sq_cmb;
- }
+ if (udata && (req.sq_cmb & IONIC_CMB_ENABLE))
+ qp->sq_cmb = req.sq_cmb;
rc = ionic_qp_sq_init(dev, ctx, qp, &req.sq, &sq_buf,
attr->cap.max_send_wr, attr->cap.max_send_sge,
@@ -2216,7 +2279,17 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
if (rc)
goto err_sq;
- if (qp->has_rq) {
+ if (QP_USES_SRQ(qp)) {
+ rq_buf.tbl_buf = NULL;
+ rq_buf.tbl_limit = 0;
+ rq_buf.tbl_pages = 0;
+
+ if (udata)
+ rc = ionic_validate_qdesc_zero(&req.rq);
+ } else {
+ if (udata && (req.rq_cmb & IONIC_CMB_ENABLE))
+ qp->rq.cmb = req.rq_cmb;
+
/* for non-srq qps, rq qid is same as qpid */
qp->rq.qid = qp->qpid;
rc = ionic_rq_init(dev, ctx, &qp->rq, &req.rq, &rq_buf,
@@ -2224,16 +2297,9 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
req.rq_spec, udata,
(qp->ibqp.qp_type == IB_QPT_DRIVER) ?
IB_ACCESS_LOCAL_WRITE : 0);
- if (rc)
- goto err_rq;
- } else {
- rq_buf.tbl_buf = NULL;
- rq_buf.tbl_limit = 0;
- rq_buf.tbl_pages = 0;
-
- if (udata)
- rc = ionic_validate_qdesc_zero(&req.rq);
}
+ if (rc)
+ goto err_rq;
rc = ionic_create_qp_cmd(dev, pd,
to_ionic_vcq_cq(attr->send_cq, qp->udma_idx),
@@ -2279,35 +2345,9 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
resp.sq_cmb = qp->sq_cmb;
}
- if (qp->rq.cmb & IONIC_CMB_ENABLE) {
- bool wc;
+ if (!QP_USES_SRQ(qp) && (qp->rq.cmb & IONIC_CMB_ENABLE)) {
+ ionic_rq_mmap_cmb(dev, ctx, &qp->rq, &resp.rq_cmb_offset);
- if ((qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) ==
- (IONIC_CMB_WC | IONIC_CMB_UC)) {
- ibdev_dbg(&dev->ibdev,
- "Both rq.cmb flags IONIC_CMB_WC and IONIC_CMB_UC are set, using default driver mapping\n");
- qp->rq.cmb &= ~(IONIC_CMB_WC | IONIC_CMB_UC);
- }
-
- if (qp->rq.cmb & IONIC_CMB_EXPDB)
- wc = (qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
- == IONIC_CMB_WC;
- else
- wc = (qp->rq.cmb & (IONIC_CMB_WC | IONIC_CMB_UC))
- != IONIC_CMB_UC;
-
- /* let userspace know the mapping */
- if (wc)
- qp->rq.cmb |= IONIC_CMB_WC;
- else
- qp->rq.cmb |= IONIC_CMB_UC;
-
- qp->rq.mmap_cmb =
- ionic_mmap_entry_insert(ctx,
- qp->rq.q.size,
- PHYS_PFN(qp->rq.cmb_addr),
- wc ? IONIC_MMAP_WC : 0,
- &resp.rq_cmb_offset);
if (!qp->rq.mmap_cmb) {
rc = -ENOMEM;
goto err_mmap_rq;
@@ -2354,7 +2394,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
qp->sq_cqid = cq->cqid;
}
- if (qp->has_rq) {
+ if (!QP_USES_SRQ(qp)) {
cq = to_ionic_vcq_cq(attr->recv_cq, qp->udma_idx);
attr->cap.max_recv_wr = qp->rq.q.mask;
@@ -2368,7 +2408,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
return 0;
err_resp:
- if (udata && (qp->rq.cmb & IONIC_CMB_ENABLE))
+ if (udata && !QP_USES_SRQ(qp) && (qp->rq.cmb & IONIC_CMB_ENABLE))
rdma_user_mmap_entry_remove(qp->rq.mmap_cmb);
err_mmap_rq:
if (udata && (qp->sq_cmb & IONIC_CMB_ENABLE))
@@ -2376,9 +2416,10 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
err_mmap_sq:
ionic_destroy_qp_cmd(dev, qp->qpid);
err_cmd:
- ionic_pgtbl_unbuf(dev, &rq_buf);
- if (qp->has_rq)
+ if (!QP_USES_SRQ(qp)) {
+ ionic_pgtbl_unbuf(dev, &rq_buf);
ionic_rq_destroy(dev, ctx, &qp->rq);
+ }
err_rq:
ionic_pgtbl_unbuf(dev, &sq_buf);
ionic_qp_sq_destroy(dev, ctx, qp);
@@ -2429,7 +2470,7 @@ void ionic_flush_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
spin_unlock_irqrestore(&cq->lock, irqflags);
}
- if (qp->ibqp.recv_cq) {
+ if (qp->ibqp.recv_cq && !QP_USES_SRQ(qp)) {
cq = to_ionic_vcq_cq(qp->ibqp.recv_cq, qp->udma_idx);
/* Hold the CQ lock and QP rq.lock to set up flush */
@@ -2505,7 +2546,7 @@ static void ionic_reset_qp(struct ionic_ibdev *dev, struct ionic_qp *qp)
spin_unlock(&qp->sq_lock);
}
- if (qp->has_rq) {
+ if (!QP_USES_SRQ(qp)) {
spin_lock(&qp->rq.lock);
qp->rq.flush = false;
qp->rq.q.prod = 0;
@@ -2610,7 +2651,7 @@ int ionic_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (qp->has_sq)
attr->cap.max_send_wr = qp->sq.mask;
- if (qp->has_rq)
+ if (!QP_USES_SRQ(qp))
attr->cap.max_recv_wr = qp->rq.q.mask;
init_attr->event_handler = ibqp->event_handler;
@@ -2667,7 +2708,7 @@ int ionic_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
spin_unlock_irqrestore(&cq->lock, irqflags);
}
- if (qp->has_rq)
+ if (!QP_USES_SRQ(qp))
ionic_rq_destroy(dev, ctx, &qp->rq);
ionic_qp_sq_destroy(dev, ctx, qp);
@@ -2679,3 +2720,221 @@ int ionic_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
return 0;
}
+
+static int ionic_create_srq_cmd(struct ionic_ibdev *dev,
+ struct ionic_ctx *ctx,
+ struct ionic_srq *srq,
+ struct ionic_pd *pd,
+ struct ionic_tbl_buf *buf)
+{
+ const u16 dbid = ionic_ctx_dbid(dev, ctx);
+ struct ionic_admin_wr wr = {
+ .work = COMPLETION_INITIALIZER_ONSTACK(wr.work),
+ .wqe = {
+ .op = IONIC_V1_ADMIN_CREATE_SRQ,
+ .len = cpu_to_le16(IONIC_ADMIN_CREATE_SRQ_IN_V1_LEN),
+ .cmd.create_srq = {
+ .pd_id = cpu_to_le32(pd->pdid),
+ .depth_log2 = srq->rq.q.depth_log2,
+ .stride_log2 = srq->rq.q.stride_log2,
+ .page_size_log2 = buf->page_size_log2,
+ .map_count = cpu_to_le32(buf->tbl_pages),
+ .dma_addr = ionic_pgtbl_dma(buf, 0),
+ .dbid = cpu_to_le16(dbid),
+ .qid = cpu_to_le32(srq->rq.qid),
+ .low_wqes_limit = cpu_to_le32(srq->srq_limit),
+ }
+ }
+ };
+
+ if (dev->lif_cfg.admin_opcodes <= IONIC_V1_ADMIN_CREATE_SRQ)
+ return -EOPNOTSUPP;
+
+ ionic_admin_post(dev, &wr);
+
+ return ionic_admin_wait(dev, &wr, 0);
+}
+
+static int ionic_destroy_srq_cmd(struct ionic_ibdev *dev, u32 srqid)
+{
+ struct ionic_admin_wr wr = {
+ .work = COMPLETION_INITIALIZER_ONSTACK(wr.work),
+ .wqe = {
+ .op = IONIC_V1_ADMIN_DESTROY_SRQ,
+ .len = cpu_to_le16(IONIC_ADMIN_DESTROY_SRQ_IN_V1_LEN),
+ .cmd.destroy_srq = {
+ .qid = cpu_to_le32(srqid),
+ },
+ }
+ };
+
+ if (dev->lif_cfg.admin_opcodes <= IONIC_V1_ADMIN_DESTROY_SRQ)
+ return -EOPNOTSUPP;
+
+ ionic_admin_post(dev, &wr);
+
+ return ionic_admin_wait(dev, &wr, IONIC_ADMIN_F_TEARDOWN);
+}
+
+static int ionic_modify_srq_cmd(struct ionic_ibdev *dev, u32 srqid,
+ u16 srq_limit)
+{
+ struct ionic_admin_wr wr = {
+ .work = COMPLETION_INITIALIZER_ONSTACK(wr.work),
+ .wqe = {
+ .op = IONIC_V1_ADMIN_MODIFY_SRQ,
+ .len = cpu_to_le16(IONIC_ADMIN_MODIFY_SRQ_IN_V1_LEN),
+ .cmd.modify_srq = {
+ .qid = cpu_to_le32(srqid),
+ .low_wqes_limit = cpu_to_le32(srq_limit),
+ },
+ }
+ };
+
+ if (dev->lif_cfg.admin_opcodes <= IONIC_V1_ADMIN_MODIFY_SRQ)
+ return -EOPNOTSUPP;
+
+ ionic_admin_post(dev, &wr);
+
+ return ionic_admin_wait(dev, &wr, IONIC_ADMIN_F_TEARDOWN);
+}
+
+int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
+ struct ib_udata *udata)
+{
+ struct ionic_ibdev *dev = to_ionic_ibdev(ibsrq->device);
+ struct ionic_pd *pd = to_ionic_pd(ibsrq->pd);
+ struct ionic_srq *srq = to_ionic_srq(ibsrq);
+ struct ionic_ctx *ctx =
+ rdma_udata_to_drv_context(udata, struct ionic_ctx, ibctx);
+ struct ionic_srq_resp resp = {};
+ struct ionic_srq_req req = {};
+ struct ionic_tbl_buf buf = {};
+ u8 udma_mask;
+ int rc;
+
+ if (attr->srq_type != IB_SRQT_BASIC)
+ return -EOPNOTSUPP;
+
+ if (attr->attr.max_sge > IONIC_MAX_SRQ_SGES)
+ return -EINVAL;
+
+ if (attr->attr.srq_limit >= IONIC_MAX_SRQ_LIMIT)
+ return -EINVAL;
+
+ udma_mask = BIT(dev->lif_cfg.udma_count) - 1;
+ if (udata) {
+ rc = ib_copy_from_udata(&req, udata,
+ min(sizeof(req), udata->inlen));
+ if (rc)
+ return rc;
+
+ udma_mask &= req.udma_mask;
+ }
+
+ if (!udma_mask)
+ return -EINVAL;
+
+ rc = ionic_get_srqid(dev, &srq->rq.qid, &srq->udma_idx, udma_mask);
+ if (rc)
+ return rc;
+
+ rc = ionic_rq_init(dev, ctx, &srq->rq, &req.rq, &buf,
+ attr->attr.max_wr, attr->attr.max_sge,
+ req.rq_spec, udata, 0);
+ if (rc)
+ goto err_rq_init;
+
+ srq->srq_limit = attr->attr.srq_limit;
+
+ rc = ionic_create_srq_cmd(dev, ctx, srq, pd, &buf);
+ if (rc)
+ goto err_cmd;
+
+ if (udata) {
+ resp.srqid = srq->rq.qid;
+ resp.udma_idx = srq->udma_idx;
+
+ if (srq->rq.cmb & IONIC_CMB_ENABLE) {
+ ionic_rq_mmap_cmb(dev, ctx, &srq->rq, &resp.rq_cmb_offset);
+ if (!srq->rq.mmap_cmb)
+ goto err_mmap_rq;
+
+ resp.rq_cmb = srq->rq.cmb;
+ }
+
+ rc = ib_copy_to_udata(udata, &resp,
+ min(sizeof(resp), udata->outlen));
+ if (rc)
+ goto err_resp;
+ }
+
+ ionic_pgtbl_unbuf(dev, &buf);
+ attr->attr.max_wr = srq->rq.q.mask;
+ return 0;
+err_resp:
+ if (udata && (srq->rq.cmb & IONIC_CMB_ENABLE))
+ rdma_user_mmap_entry_remove(srq->rq.mmap_cmb);
+err_mmap_rq:
+ ionic_destroy_srq_cmd(dev, srq->rq.qid);
+err_cmd:
+ ionic_pgtbl_unbuf(dev, &buf);
+ ionic_rq_destroy(dev, ctx, &srq->rq);
+err_rq_init:
+ ionic_put_srqid(dev, srq->rq.qid);
+ return rc;
+}
+
+int ionic_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
+{
+ struct ionic_ctx *ctx =
+ rdma_udata_to_drv_context(udata, struct ionic_ctx, ibctx);
+ struct ionic_ibdev *dev = to_ionic_ibdev(ibsrq->device);
+ struct ionic_srq *srq = to_ionic_srq(ibsrq);
+ int rc;
+
+ rc = ionic_destroy_srq_cmd(dev, srq->rq.qid);
+ if (rc)
+ return rc;
+
+ ionic_rq_destroy(dev, ctx, &srq->rq);
+ ionic_put_srqid(dev, srq->rq.qid);
+ return 0;
+}
+
+int ionic_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
+{
+ struct ionic_srq *srq = to_ionic_srq(ibsrq);
+
+ srq_attr->max_wr = srq->rq.q.mask;
+ srq_attr->max_sge =
+ ionic_v1_recv_wqe_max_sge(srq->rq.q.stride_log2, srq->rq.spec,
+ srq->rq.cmb & IONIC_CMB_EXPDB);
+ srq_attr->srq_limit = srq->srq_limit;
+
+ return 0;
+}
+
+int ionic_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
+{
+ struct ionic_ibdev *dev = to_ionic_ibdev(ibsrq->device);
+ struct ionic_srq *srq = to_ionic_srq(ibsrq);
+ int rc;
+
+ if (attr_mask & IB_SRQ_MAX_WR)
+ return -EINVAL;
+
+ if (attr_mask & IB_SRQ_LIMIT) {
+ if (attr->srq_limit >= IONIC_MAX_SRQ_LIMIT)
+ return -EINVAL;
+
+ rc = ionic_modify_srq_cmd(dev, srq->rq.qid, attr->srq_limit);
+ if (rc)
+ return rc;
+
+ srq->srq_limit = attr->srq_limit;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
index b8fa6b6e5f33..b050f2e84f6b 100644
--- a/drivers/infiniband/hw/ionic/ionic_datapath.c
+++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
@@ -1310,7 +1310,7 @@ static int ionic_post_recv_common(struct ionic_ibdev *dev,
if (!bad)
return -EINVAL;
- if (!qp->has_rq) {
+ if (qp->srq) {
*bad = wr;
return -EINVAL;
}
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index adfbb89d856c..632b16932844 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h
@@ -88,6 +88,10 @@ static inline int to_ionic_mr_flags(int access)
return flags;
}
+enum ionic_srq_flags {
+ IONIC_SRQF_CMB = BIT(0),
+};
+
enum ionic_qp_flags {
/* bits that determine qp access */
IONIC_QPF_REMOTE_WRITE = BIT(0),
@@ -838,6 +842,37 @@ struct ionic_admin_query_qp {
static_assert(sizeof(struct ionic_admin_query_qp) ==
IONIC_ADMIN_QUERY_QP_IN_V1_LEN);
+struct ionic_admin_create_srq {
+ __le64 dma_addr;
+ __le32 map_count;
+ __le32 pd_id;
+ __le32 qid;
+ __le16 dbid;
+ __le16 low_wqes_limit;
+ __le16 flags;
+ __u8 depth_log2;
+ __u8 stride_log2;
+ __u8 page_size_log2;
+} __packed;
+
+#define IONIC_ADMIN_CREATE_SRQ_IN_V1_LEN 29
+static_assert(sizeof(struct ionic_admin_create_srq) == IONIC_ADMIN_CREATE_SRQ_IN_V1_LEN);
+
+struct ionic_admin_modify_srq {
+ __le32 qid;
+ __le16 low_wqes_limit;
+} __packed;
+
+#define IONIC_ADMIN_MODIFY_SRQ_IN_V1_LEN 6
+static_assert(sizeof(struct ionic_admin_modify_srq) == IONIC_ADMIN_MODIFY_SRQ_IN_V1_LEN);
+
+struct ionic_admin_destroy_srq {
+ __le32 qid;
+} __packed;
+
+#define IONIC_ADMIN_DESTROY_SRQ_IN_V1_LEN 4
+static_assert(sizeof(struct ionic_admin_destroy_srq) == IONIC_ADMIN_DESTROY_SRQ_IN_V1_LEN);
+
#define ADMIN_WQE_STRIDE 64
#define ADMIN_WQE_HDR_LEN 4
@@ -860,6 +895,9 @@ struct ionic_v1_admin_wqe {
struct ionic_admin_destroy_qp destroy_qp;
struct ionic_admin_mod_qp mod_qp;
struct ionic_admin_query_qp query_qp;
+ struct ionic_admin_create_srq create_srq;
+ struct ionic_admin_modify_srq modify_srq;
+ struct ionic_admin_destroy_srq destroy_srq;
} cmd;
};
@@ -906,6 +944,10 @@ enum ionic_v1_admin_op {
IONIC_V1_ADMIN_DESTROY_AH,
IONIC_V1_ADMIN_QP_STATS_HDRS,
IONIC_V1_ADMIN_QP_STATS_VALS,
+ IONIC_V1_ADMIN_CREATE_SRQ = 26,
+ IONIC_V1_ADMIN_MODIFY_SRQ,
+ IONIC_V1_ADMIN_QUERY_SRQ,
+ IONIC_V1_ADMIN_DESTROY_SRQ,
IONIC_V1_ADMIN_OPCODES_MAX,
};
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.c b/drivers/infiniband/hw/ionic/ionic_ibdev.c
index 164046d00e5d..d8a8e74f56ac 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.c
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.c
@@ -68,6 +68,11 @@ static int ionic_query_device(struct ib_device *ibdev,
attr->max_ah = dev->lif_cfg.nahs_per_lif;
attr->max_fast_reg_page_list_len = dev->lif_cfg.npts_per_lif / 2;
attr->max_pkeys = IONIC_PKEY_TBL_LEN;
+ if (dev->lif_cfg.srq_count) {
+ attr->max_srq = dev->lif_cfg.srq_count;
+ attr->max_srq_wr = IONIC_MAX_SRQ_DEPTH;
+ attr->max_srq_sge = IONIC_MAX_SRQ_SGES;
+ }
return 0;
}
@@ -258,6 +263,15 @@ static const struct ib_device_ops ionic_dev_ops = {
INIT_RDMA_OBJ_SIZE(ib_mw, ionic_mr, ibmw),
};
+static const struct ib_device_ops ionic_srq_ops = {
+ .create_srq = ionic_create_srq,
+ .modify_srq = ionic_modify_srq,
+ .query_srq = ionic_query_srq,
+ .destroy_srq = ionic_destroy_srq,
+
+ INIT_RDMA_OBJ_SIZE(ib_srq, ionic_srq, ibsrq),
+};
+
static void ionic_init_resids(struct ionic_ibdev *dev)
{
ionic_resid_init(&dev->inuse_cqid, dev->lif_cfg.cq_count);
@@ -346,6 +360,8 @@ static struct ionic_ibdev *ionic_create_ibdev(struct ionic_aux_dev *ionic_adev)
goto err_admin;
ib_set_device_ops(&dev->ibdev, &ionic_dev_ops);
+ if (dev->lif_cfg.srq_count)
+ ib_set_device_ops(&dev->ibdev, &ionic_srq_ops);
ionic_stats_init(dev);
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.h b/drivers/infiniband/hw/ionic/ionic_ibdev.h
index 5517638d4ced..895672283264 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.h
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.h
@@ -33,10 +33,13 @@
#define IONIC_MAX_QPID 0xffffff
#define IONIC_SPEC_HIGH 8
#define IONIC_MAX_PD 1024
-#define IONIC_SPEC_HIGH 8
#define IONIC_SQCMB_ORDER 5
#define IONIC_RQCMB_ORDER 0
+#define IONIC_MAX_SRQ_SGES 2
+#define IONIC_MAX_SRQ_LIMIT 0xffff
+#define IONIC_MAX_SRQ_DEPTH 0xffff
+
#define IONIC_META_LAST ((void *)1ul)
#define IONIC_META_POSTED ((void *)2ul)
@@ -116,6 +119,7 @@ struct ionic_ibdev {
struct rdma_stat_desc *hw_stats_hdrs;
struct ionic_counter_stats *counter_stats;
int hw_stats_count;
+ u8 next_srqid_udma_idx;
};
struct ionic_eq {
@@ -265,6 +269,13 @@ struct ionic_rq {
bool flush;
};
+struct ionic_srq {
+ struct ib_srq ibsrq;
+ struct ionic_rq rq;
+ u16 srq_limit;
+ u8 udma_idx;
+};
+
struct ionic_qp {
struct ib_qp ibqp;
enum ib_qp_state state;
@@ -275,7 +286,6 @@ struct ionic_qp {
u8 udma_idx;
u8 has_ah:1;
u8 has_sq:1;
- u8 has_rq:1;
u8 sig_all:1;
struct list_head qp_list_counter;
@@ -314,6 +324,7 @@ struct ionic_qp {
int dcqcn_profile;
struct ib_ud_header *hdr;
+ struct ionic_srq *srq;
};
struct ionic_ah {
@@ -401,6 +412,11 @@ static inline struct ionic_qp *to_ionic_qp(struct ib_qp *ibqp)
return container_of(ibqp, struct ionic_qp, ibqp);
}
+static inline struct ionic_srq *to_ionic_srq(struct ib_srq *ibsrq)
+{
+ return container_of(ibsrq, struct ionic_srq, ibsrq);
+}
+
static inline struct ionic_ah *to_ionic_ah(struct ib_ah *ibah)
{
return container_of(ibah, struct ionic_ah, ibah);
@@ -500,6 +516,12 @@ int ionic_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int mask,
int ionic_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int mask,
struct ib_qp_init_attr *init_attr);
int ionic_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
+int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
+ struct ib_udata *udata);
+int ionic_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata);
+int ionic_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr);
+int ionic_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
/* ionic_datapath.c */
int ionic_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
index f3cd281c3a2f..35e2f0f620cd 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.c
@@ -73,6 +73,7 @@ void ionic_fill_lif_cfg(struct ionic_lif *lif, struct ionic_lif_cfg *cfg)
cfg->eq_count = le32_to_cpu(ident->rdma.eq_qtype.qid_count);
cfg->cq_count = le32_to_cpu(ident->rdma.cq_qtype.qid_count);
cfg->qp_count = le32_to_cpu(ident->rdma.sq_qtype.qid_count);
+ cfg->srq_count = le32_to_cpu(ident->rdma.srq_qtype.qid_count);
cfg->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif);
cfg->aq_qtype = ident->rdma.aq_qtype.qtype;
diff --git a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
index 20853429f623..0ffff7178c90 100644
--- a/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
+++ b/drivers/infiniband/hw/ionic/ionic_lif_cfg.h
@@ -37,6 +37,7 @@ struct ionic_lif_cfg {
int eq_count;
int cq_count;
int qp_count;
+ int srq_count;
u16 stats_type;
u8 aq_qtype;
diff --git a/include/uapi/rdma/ionic-abi.h b/include/uapi/rdma/ionic-abi.h
index 7b589d3e9728..b89ae42f5126 100644
--- a/include/uapi/rdma/ionic-abi.h
+++ b/include/uapi/rdma/ionic-abi.h
@@ -105,7 +105,7 @@ struct ionic_srq_req {
};
struct ionic_srq_resp {
- __u32 qpid;
+ __u32 srqid;
__u8 rq_cmb;
__u8 udma_idx;
__u8 rsvd[2];
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 4/4] RDMA/ionic: implement SRQ event handling support
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (7 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 3/4] RDMA/ionic: add Shared receive queue (SRQ) support Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (6 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
Introduce SRQ event types and associated events. Report these events
through the SRQ event handler during event processing.
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/infiniband/hw/ionic/ionic_admin.c | 47 +++++++++++++++++++
.../infiniband/hw/ionic/ionic_controlpath.c | 19 ++++++++
drivers/infiniband/hw/ionic/ionic_fw.h | 6 ++-
drivers/infiniband/hw/ionic/ionic_ibdev.c | 4 ++
drivers/infiniband/hw/ionic/ionic_ibdev.h | 10 ++++
5 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_admin.c b/drivers/infiniband/hw/ionic/ionic_admin.c
index 2537aa55d12d..ad8a45d09252 100644
--- a/drivers/infiniband/hw/ionic/ionic_admin.c
+++ b/drivers/infiniband/hw/ionic/ionic_admin.c
@@ -890,6 +890,49 @@ static void ionic_qp_event(struct ionic_ibdev *dev, u32 qpid, u8 code)
kref_put(&qp->qp_kref, ionic_qp_complete);
}
+static void ionic_srq_event(struct ionic_ibdev *dev, u32 srqid, u8 code)
+{
+ struct ionic_srq *srq;
+ struct ib_event ibev;
+ unsigned long irqflags;
+
+ xa_lock_irqsave(&dev->srq_tbl, irqflags);
+ srq = xa_load(&dev->srq_tbl, srqid);
+ if (srq)
+ kref_get(&srq->kref);
+ xa_unlock_irqrestore(&dev->srq_tbl, irqflags);
+
+ if (!srq) {
+ ibdev_dbg(&dev->ibdev,
+ "missing srqid %#x code %u\n", srqid, code);
+ return;
+ }
+
+ ibev.device = &dev->ibdev;
+ ibev.element.srq = &srq->ibsrq;
+
+ switch (code) {
+ case IONIC_V1_EQE_SRQ_LIMIT_REACHED:
+ ibev.event = IB_EVENT_SRQ_LIMIT_REACHED;
+ break;
+
+ case IONIC_V1_EQE_SRQ_ERR:
+ ibev.event = IB_EVENT_SRQ_ERR;
+ break;
+
+ default:
+ ibdev_dbg(&dev->ibdev,
+ "unrecognized srqid %#x code %u\n", srqid, code);
+ goto out;
+ }
+
+ if (srq->ibsrq.event_handler)
+ srq->ibsrq.event_handler(&ibev, srq->ibsrq.srq_context);
+
+out:
+ kref_put(&srq->kref, ionic_srq_complete);
+}
+
static u16 ionic_poll_eq(struct ionic_eq *eq, u16 budget)
{
struct ionic_ibdev *dev = eq->dev;
@@ -923,6 +966,10 @@ static u16 ionic_poll_eq(struct ionic_eq *eq, u16 budget)
ionic_qp_event(dev, qid, code);
break;
+ case IONIC_V1_EQE_TYPE_SRQ:
+ ionic_srq_event(dev, qid, code);
+ break;
+
default:
ibdev_dbg(&dev->ibdev,
"unknown event %#x type %u\n", evt, type);
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 35eb08dd0761..2525deb7a229 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -2811,6 +2811,7 @@ int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
struct ionic_srq_req req = {};
struct ionic_tbl_buf buf = {};
u8 udma_mask;
+ void *entry;
int rc;
if (attr->srq_type != IB_SRQT_BASIC)
@@ -2869,6 +2870,19 @@ int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
goto err_resp;
}
+ kref_init(&srq->kref);
+ init_completion(&srq->rel_comp);
+
+ entry = xa_store_irq(&dev->srq_tbl, srq->rq.qid, srq, GFP_KERNEL);
+ if (entry) {
+ if (!xa_is_err(entry))
+ rc = -EINVAL;
+ else
+ rc = xa_err(entry);
+
+ goto err_resp;
+ }
+
ionic_pgtbl_unbuf(dev, &buf);
attr->attr.max_wr = srq->rq.q.mask;
return 0;
@@ -2897,6 +2911,11 @@ int ionic_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
if (rc)
return rc;
+ xa_erase_irq(&dev->srq_tbl, srq->rq.qid);
+
+ kref_put(&srq->kref, ionic_srq_complete);
+ wait_for_completion(&srq->rel_comp);
+
ionic_rq_destroy(dev, ctx, &srq->rq);
ionic_put_srqid(dev, srq->rq.qid);
return 0;
diff --git a/drivers/infiniband/hw/ionic/ionic_fw.h b/drivers/infiniband/hw/ionic/ionic_fw.h
index 632b16932844..eafadb0a16c7 100644
--- a/drivers/infiniband/hw/ionic/ionic_fw.h
+++ b/drivers/infiniband/hw/ionic/ionic_fw.h
@@ -983,7 +983,7 @@ enum ionic_v1_eqe_evt_bits {
/* cq error events */
IONIC_V1_EQE_CQ_ERR = 8,
- /* qp and srq events */
+ /* qp events */
IONIC_V1_EQE_TYPE_QP = 1,
/* qp normal events */
IONIC_V1_EQE_SRQ_LEVEL = 0,
@@ -994,6 +994,10 @@ enum ionic_v1_eqe_evt_bits {
IONIC_V1_EQE_QP_ERR = 8,
IONIC_V1_EQE_QP_ERR_REQUEST = 9,
IONIC_V1_EQE_QP_ERR_ACCESS = 10,
+ /* srq events */
+ IONIC_V1_EQE_TYPE_SRQ = 2,
+ IONIC_V1_EQE_SRQ_LIMIT_REACHED = 0,
+ IONIC_V1_EQE_SRQ_ERR = 1,
};
enum ionic_tfp_csum_profiles {
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.c b/drivers/infiniband/hw/ionic/ionic_ibdev.c
index d8a8e74f56ac..3b4abfc41ca4 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.c
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.c
@@ -310,6 +310,8 @@ static void ionic_destroy_ibdev(struct ionic_ibdev *dev)
xa_destroy(&dev->qp_tbl);
WARN_ON(!xa_empty(&dev->cq_tbl));
xa_destroy(&dev->cq_tbl);
+ WARN_ON(!xa_empty(&dev->srq_tbl));
+ xa_destroy(&dev->srq_tbl);
ib_dealloc_device(&dev->ibdev);
}
@@ -328,6 +330,7 @@ static struct ionic_ibdev *ionic_create_ibdev(struct ionic_aux_dev *ionic_adev)
xa_init_flags(&dev->qp_tbl, GFP_ATOMIC);
xa_init_flags(&dev->cq_tbl, GFP_ATOMIC);
+ xa_init_flags(&dev->srq_tbl, GFP_ATOMIC);
ionic_init_resids(dev);
@@ -380,6 +383,7 @@ static struct ionic_ibdev *ionic_create_ibdev(struct ionic_aux_dev *ionic_adev)
ionic_destroy_resids(dev);
xa_destroy(&dev->qp_tbl);
xa_destroy(&dev->cq_tbl);
+ xa_destroy(&dev->srq_tbl);
ib_dealloc_device(&dev->ibdev);
return ERR_PTR(rc);
diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.h b/drivers/infiniband/hw/ionic/ionic_ibdev.h
index 895672283264..e29f11b38036 100644
--- a/drivers/infiniband/hw/ionic/ionic_ibdev.h
+++ b/drivers/infiniband/hw/ionic/ionic_ibdev.h
@@ -91,6 +91,7 @@ struct ionic_ibdev {
struct xarray qp_tbl;
struct xarray cq_tbl;
+ struct xarray srq_tbl;
struct ionic_resid_bits inuse_dbid;
struct ionic_resid_bits inuse_pdid;
@@ -272,6 +273,8 @@ struct ionic_rq {
struct ionic_srq {
struct ib_srq ibsrq;
struct ionic_rq rq;
+ struct kref kref;
+ struct completion rel_comp;
u16 srq_limit;
u8 udma_idx;
};
@@ -456,6 +459,13 @@ static inline void ionic_cq_complete(struct kref *kref)
complete(&cq->cq_rel_comp);
}
+static inline void ionic_srq_complete(struct kref *kref)
+{
+ struct ionic_srq *srq = container_of(kref, struct ionic_srq, kref);
+
+ complete(&srq->rel_comp);
+}
+
/* ionic_admin.c */
extern struct workqueue_struct *ionic_evt_workq;
void ionic_admin_post(struct ionic_ibdev *dev, struct ionic_admin_wr *wr);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v3 0/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (8 preceding siblings ...)
2026-07-07 9:55 ` [PATCH 4/4] RDMA/ionic: implement SRQ event handling support Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v3 1/1] " Abhijit Gangurde
` (5 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
This is a resubmission of the remaining patch from v2 series.
Patch 2/2 from v2 ("cdx: disable cdx bus from bus shutdown callback")
was already merged as commit 6d2478a103a8.
This patch registers the shutdown callback for the cdx controller
platform device to handle graceful connection closure of rpmsg
transport during system shutdown/reboot.
v3:
- Rebased on v7.2-rc1
- Dropped patch 2/2 (already merged)
v2:
- Split single patch into two
- https://lore.kernel.org/all/20241203084409.2747897-1-abhijit.gangurde@amd.com/
Abhijit Gangurde (1):
cdx: register shutdown callback for cdx controller
drivers/cdx/controller/cdx_controller.c | 6 ++++++
1 file changed, 6 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread* [PATCH v3 1/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (9 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v99 1/1] One more fix Abhijit Gangurde
` (4 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde,
Nikhil Agarwal
Register shutdown callback for cdx controller platform device
to handle graceful connection closure of rpmsg transport.
Reviewed-by: Nikhil Agarwal <Nikhil.agarwal@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/cdx/controller/cdx_controller.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c
index 280bb7490c0f..2295b8bfe87e 100644
--- a/drivers/cdx/controller/cdx_controller.c
+++ b/drivers/cdx/controller/cdx_controller.c
@@ -234,6 +234,11 @@ static void xlnx_cdx_remove(struct platform_device *pdev)
kfree(cdx_mcdi);
}
+static void xlnx_cdx_shutdown(struct platform_device *pdev)
+{
+ cdx_destroy_rpmsg(pdev);
+}
+
static const struct of_device_id cdx_match_table[] = {
{.compatible = "xlnx,versal-net-cdx",},
{ },
@@ -248,6 +253,7 @@ static struct platform_driver cdx_pdriver = {
},
.probe = xlnx_cdx_probe,
.remove = xlnx_cdx_remove,
+ .shutdown = xlnx_cdx_shutdown,
};
module_platform_driver(cdx_pdriver);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v99 1/1] One more fix
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (10 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v3 1/1] " Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 10:06 ` Greg KH
2026-07-07 9:55 ` [PATCH v99 1/1] merge me Abhijit Gangurde
` (3 subsequent siblings)
15 siblings, 1 reply; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
---
drivers/infiniband/hw/ionic/ionic_controlpath.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 1ed45e1dd98d..a635bb472826 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -2845,8 +2845,10 @@ int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
if (srq->rq.cmb & IONIC_CMB_ENABLE) {
ionic_rq_mmap_cmb(dev, ctx, &srq->rq, &resp.rq_cmb_offset);
- if (!srq->rq.mmap_cmb)
+ if (!srq->rq.mmap_cmb) {
+ rc = -ENOMEM;
goto err_mmap_rq;
+ }
resp.rq_cmb = srq->rq.cmb;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v99 1/1] One more fix
2026-07-07 9:55 ` [PATCH v99 1/1] One more fix Abhijit Gangurde
@ 2026-07-07 10:06 ` Greg KH
2026-07-07 10:13 ` Abhijit Gangurde
0 siblings, 1 reply; 23+ messages in thread
From: Greg KH @ 2026-07-07 10:06 UTC (permalink / raw)
To: Abhijit Gangurde
Cc: nipun.gupta, nikhil.agarwal, linux-kernel, michal.simek, git
On Tue, Jul 07, 2026 at 03:25:52PM +0530, Abhijit Gangurde wrote:
> ---
> drivers/infiniband/hw/ionic/ionic_controlpath.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
> index 1ed45e1dd98d..a635bb472826 100644
> --- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
> +++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
> @@ -2845,8 +2845,10 @@ int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
>
> if (srq->rq.cmb & IONIC_CMB_ENABLE) {
> ionic_rq_mmap_cmb(dev, ctx, &srq->rq, &resp.rq_cmb_offset);
> - if (!srq->rq.mmap_cmb)
> + if (!srq->rq.mmap_cmb) {
> + rc = -ENOMEM;
> goto err_mmap_rq;
> + }
>
> resp.rq_cmb = srq->rq.cmb;
> }
> --
> 2.43.0
>
Something went really wrong with this series :(
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH v99 1/1] One more fix
2026-07-07 10:06 ` Greg KH
@ 2026-07-07 10:13 ` Abhijit Gangurde
0 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 10:13 UTC (permalink / raw)
To: Greg KH; +Cc: nipun.gupta, nikhil.agarwal, linux-kernel, michal.simek, git
On 7/7/26 15:36, Greg KH wrote:
> On Tue, Jul 07, 2026 at 03:25:52PM +0530, Abhijit Gangurde wrote:
>> ---
>> drivers/infiniband/hw/ionic/ionic_controlpath.c | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
>> index 1ed45e1dd98d..a635bb472826 100644
>> --- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
>> +++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
>> @@ -2845,8 +2845,10 @@ int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
>>
>> if (srq->rq.cmb & IONIC_CMB_ENABLE) {
>> ionic_rq_mmap_cmb(dev, ctx, &srq->rq, &resp.rq_cmb_offset);
>> - if (!srq->rq.mmap_cmb)
>> + if (!srq->rq.mmap_cmb) {
>> + rc = -ENOMEM;
>> goto err_mmap_rq;
>> + }
>>
>> resp.rq_cmb = srq->rq.cmb;
>> }
>> --
>> 2.43.0
>>
> Something went really wrong with this series :(
All,
My sincere apologies for the noise. I accidentally sent a batch of
unrelated local patches to this thread. That was entirely unintentional.
Please disregard all patches in this series.
I will resend just the correct patch as a clean v3 to avoid any
confusion.
Again, sorry for the spam.
Abhijit
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v99 1/1] merge me
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (11 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v99 1/1] One more fix Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (2 subsequent siblings)
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
---
drivers/infiniband/hw/ionic/ionic_controlpath.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 48c05b0c1c95..1ed45e1dd98d 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -294,8 +294,7 @@ static int ionic_get_qpid(struct ionic_ibdev *dev, u32 *qpid,
static int ionic_get_srqid(struct ionic_ibdev *dev, u32 *srqid,
u8 *udma_idx, u8 udma_mask)
{
- if (udma_mask &&
- !(udma_mask & dev->next_srqid_udma_idx))
+ if (udma_mask && !(udma_mask & BIT(dev->next_srqid_udma_idx)))
/* flip udma idx if it doesn't coincide with udma_mask */
dev->next_srqid_udma_idx ^= dev->lif_cfg.udma_count - 1;
@@ -2730,7 +2729,7 @@ static int ionic_create_srq_cmd(struct ionic_ibdev *dev,
.dma_addr = ionic_pgtbl_dma(buf, 0),
.dbid = cpu_to_le16(dbid),
.qid = cpu_to_le32(srq->rq.qid),
- .low_wqes_limit = cpu_to_le32(srq->srq_limit),
+ .low_wqes_limit = cpu_to_le16(srq->srq_limit),
}
}
};
@@ -2774,7 +2773,7 @@ static int ionic_modify_srq_cmd(struct ionic_ibdev *dev, u32 srqid,
.len = cpu_to_le16(IONIC_ADMIN_MODIFY_SRQ_IN_V1_LEN),
.cmd.modify_srq = {
.qid = cpu_to_le32(srqid),
- .low_wqes_limit = cpu_to_le32(srq_limit),
+ .low_wqes_limit = cpu_to_le16(srq_limit),
},
}
};
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v3 0/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (12 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v99 1/1] merge me Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 9:55 ` [PATCH v3 1/1] " Abhijit Gangurde
2026-07-07 10:06 ` [PATCH v3 0/1] " Michal Simek
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde
This is a resubmission of the remaining patch from v2 series.
Patch 2/2 from v2 ("cdx: disable cdx bus from bus shutdown callback")
was already merged as commit 6d2478a103a8.
This patch registers the shutdown callback for the cdx controller
platform device to handle graceful connection closure of rpmsg
transport during system shutdown/reboot.
v3:
- Rebased on v7.2-rc1
- Dropped patch 2/2 (already merged)
v2:
- Split single patch into two
- https://lore.kernel.org/all/20241203084409.2747897-1-abhijit.gangurde@amd.com/
Abhijit Gangurde (1):
cdx: register shutdown callback for cdx controller
drivers/cdx/controller/cdx_controller.c | 6 ++++++
1 file changed, 6 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread* [PATCH v3 1/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (13 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
@ 2026-07-07 9:55 ` Abhijit Gangurde
2026-07-07 10:06 ` [PATCH v3 0/1] " Michal Simek
15 siblings, 0 replies; 23+ messages in thread
From: Abhijit Gangurde @ 2026-07-07 9:55 UTC (permalink / raw)
To: nipun.gupta, nikhil.agarwal
Cc: gregkh, linux-kernel, michal.simek, git, Abhijit Gangurde,
Nikhil Agarwal
Register shutdown callback for cdx controller platform device
to handle graceful connection closure of rpmsg transport.
Reviewed-by: Nikhil Agarwal <Nikhil.agarwal@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
---
drivers/cdx/controller/cdx_controller.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c
index 280bb7490c0f..2295b8bfe87e 100644
--- a/drivers/cdx/controller/cdx_controller.c
+++ b/drivers/cdx/controller/cdx_controller.c
@@ -234,6 +234,11 @@ static void xlnx_cdx_remove(struct platform_device *pdev)
kfree(cdx_mcdi);
}
+static void xlnx_cdx_shutdown(struct platform_device *pdev)
+{
+ cdx_destroy_rpmsg(pdev);
+}
+
static const struct of_device_id cdx_match_table[] = {
{.compatible = "xlnx,versal-net-cdx",},
{ },
@@ -248,6 +253,7 @@ static struct platform_driver cdx_pdriver = {
},
.probe = xlnx_cdx_probe,
.remove = xlnx_cdx_remove,
+ .shutdown = xlnx_cdx_shutdown,
};
module_platform_driver(cdx_pdriver);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v3 0/1] cdx: register shutdown callback for cdx controller
2026-07-07 9:55 [PATCH v3 0/1] cdx: register shutdown callback for cdx controller Abhijit Gangurde
` (14 preceding siblings ...)
2026-07-07 9:55 ` [PATCH v3 1/1] " Abhijit Gangurde
@ 2026-07-07 10:06 ` Michal Simek
15 siblings, 0 replies; 23+ messages in thread
From: Michal Simek @ 2026-07-07 10:06 UTC (permalink / raw)
To: Abhijit Gangurde, nipun.gupta, nikhil.agarwal; +Cc: gregkh, linux-kernel, git
On 7/7/26 11:55, Abhijit Gangurde wrote:
> This is a resubmission of the remaining patch from v2 series.
> Patch 2/2 from v2 ("cdx: disable cdx bus from bus shutdown callback")
> was already merged as commit 6d2478a103a8.
>
> This patch registers the shutdown callback for the cdx controller
> platform device to handle graceful connection closure of rpmsg
> transport during system shutdown/reboot.
>
> Changes v2->v3:
> - Rebased on v7.2-rc1
> - Dropped patch 2/2 (already merged)
>
> Changes v1->v2:
> - Split single patch into two (Greg KH)
> - https://lore.kernel.org/all/20241203084409.2747897-1-abhijit.gangurde@amd.com/
>
>
> Abhijit Gangurde (1):
> cdx: register shutdown callback for cdx controller
>
> drivers/cdx/controller/cdx_controller.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
>
> base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
hm. This is just a mess. I see 4 series in the same thread. Some temporary
patches, etc.
Please look at
https://lore.kernel.org/all/20260707095555.3939295-1-abhijit.gangurde@amd.com/
And send it properly next time.
M
^ permalink raw reply [flat|nested] 23+ messages in thread