git: c957af2c210a - main - iw_cxgbe/libcxgb4: Support 64B CQEs

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Tue, 15 Sep 2026 14:47:40 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=c957af2c210aa3d7b72a886b663b9f425baa3186

commit c957af2c210aa3d7b72a886b663b9f425baa3186
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-09-14 15:37:08 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-09-15 14:22:38 +0000

    iw_cxgbe/libcxgb4: Support 64B CQEs
    
    The larger CQE exports the RSS header to userspace.  Note that this
    changes the ABI between the driver and library, so the ABI version is
    bumped.  A new user->kernel create_cq request message is defined to
    disallow a CQE size mismatch between iw_cxgbe and libcxgb4.
    
    Sponsored by:   Chelsio Communications
    Co-authored-by: Steve Wise <swise@opengridcomputing.com>
---
 contrib/ofed/libcxgb4/cxgb4-abi.h |  5 +++++
 contrib/ofed/libcxgb4/libcxgb4.h  |  2 +-
 contrib/ofed/libcxgb4/t4.h        |  6 ++++--
 contrib/ofed/libcxgb4/verbs.c     | 12 ++++++++++--
 lib/ofed/libcxgb4/Makefile        |  1 +
 sys/dev/cxgbe/iw_cxgbe/cq.c       |  5 ++---
 sys/dev/cxgbe/iw_cxgbe/t4.h       |  7 ++++++-
 sys/dev/cxgbe/iw_cxgbe/user.h     |  6 +++++-
 8 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/contrib/ofed/libcxgb4/cxgb4-abi.h b/contrib/ofed/libcxgb4/cxgb4-abi.h
index 91e68d552b29..a42012c1ff0e 100644
--- a/contrib/ofed/libcxgb4/cxgb4-abi.h
+++ b/contrib/ofed/libcxgb4/cxgb4-abi.h
@@ -47,6 +47,11 @@ struct c4iw_alloc_pd_resp {
 	uint32_t pdid;
 };
 
+struct c4iw_create_cq_req {
+	struct ibv_create_cq ibv_req;
+	__u64 cqe_size;
+};
+
 struct c4iw_create_cq_resp {
 	struct ibv_create_cq_resp ibv_resp;
 	__u64 key;
diff --git a/contrib/ofed/libcxgb4/libcxgb4.h b/contrib/ofed/libcxgb4/libcxgb4.h
index 216eee05a9d8..94700db03e3f 100644
--- a/contrib/ofed/libcxgb4/libcxgb4.h
+++ b/contrib/ofed/libcxgb4/libcxgb4.h
@@ -97,7 +97,7 @@ struct c4iw_pd {
 struct c4iw_mr {
 	struct ibv_mr ibv_mr;
 	uint64_t va_fbo;
-	uint32_t len;
+	uint64_t len;
 };
 
 static inline u32 c4iw_mmid(u32 stag)
diff --git a/contrib/ofed/libcxgb4/t4.h b/contrib/ofed/libcxgb4/t4.h
index ba7d578bf390..87c2d4ee82df 100644
--- a/contrib/ofed/libcxgb4/t4.h
+++ b/contrib/ofed/libcxgb4/t4.h
@@ -63,6 +63,7 @@
 #include "t4_regs.h"
 #include "t4_chip_type.h"
 #include "t4fw_interface.h"
+#include "t4_msg.h"
 
 #ifdef DEBUG
 #define DBGLOG(s)
@@ -192,9 +193,10 @@ static inline void init_wr_hdr(union t4_wr *wqe, u16 wrid,
 #define T4_ERR_INTERNAL_ERR                0x1F /* internal error (opcode  */
 						/* mismatch) */
 /*
- * CQE defs
+ * 64B CQE entries.
  */
 struct t4_cqe {
+	struct rss_header rss;
 	__be32 header;
 	__be32 len;
 	union {
@@ -212,7 +214,7 @@ struct t4_cqe {
 			__be32 wrid_low;
 		} gen;
 	} u;
-	__be64 reserved;
+	__be64 reserved[4];
 	__be64 bits_type_ts;
 };
 
diff --git a/contrib/ofed/libcxgb4/verbs.c b/contrib/ofed/libcxgb4/verbs.c
index 4e44b2285fff..6188134146a9 100644
--- a/contrib/ofed/libcxgb4/verbs.c
+++ b/contrib/ofed/libcxgb4/verbs.c
@@ -168,20 +168,28 @@ int c4iw_dereg_mr(struct ibv_mr *mr)
 struct ibv_cq *c4iw_create_cq(struct ibv_context *context, int cqe,
 			      struct ibv_comp_channel *channel, int comp_vector)
 {
-	struct ibv_create_cq cmd;
+	struct c4iw_create_cq_req cmd;
 	struct c4iw_create_cq_resp resp;
 	struct c4iw_cq *chp;
 	struct c4iw_dev *dev = to_c4iw_dev(context->device);
 	int ret;
 
+	if (dev->abi_version < 5) {
+		fprintf(stderr, "libcxgb4 FATAL ERROR: downlevel iw_cxgb4 "
+			"module.  Cannot support RDMA with this driver/lib"
+			" combination.  Update your drivers!\n");
+		return NULL;
+	}
+
 	chp = calloc(1, sizeof *chp);
 	if (!chp) {
 		return NULL;
 	}
 
+	cmd.cqe_size = sizeof *chp->cq.queue;
 	resp.reserved = 0;
 	ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector,
-				&chp->ibv_cq, &cmd, sizeof cmd,
+				&chp->ibv_cq, &cmd.ibv_req, sizeof cmd,
 				&resp.ibv_resp, sizeof resp);
 	if (ret)
 		goto err1;
diff --git a/lib/ofed/libcxgb4/Makefile b/lib/ofed/libcxgb4/Makefile
index 23a9d63477a7..d74e5d19195d 100644
--- a/lib/ofed/libcxgb4/Makefile
+++ b/lib/ofed/libcxgb4/Makefile
@@ -13,6 +13,7 @@ verbs.c
 
 LIBADD=		ibverbs pthread
 CFLAGS+=	-I${_spath}
+CFLAGS+=	-I${SRCTOP}/sys/dev/cxgbe/common
 CFLAGS+=	-I${SRCTOP}/sys/dev/cxgbe/firmware
 
 .include <bsd.lib.mk>
diff --git a/sys/dev/cxgbe/iw_cxgbe/cq.c b/sys/dev/cxgbe/iw_cxgbe/cq.c
index 197f2bcf8af0..02ee18ebd60c 100644
--- a/sys/dev/cxgbe/iw_cxgbe/cq.c
+++ b/sys/dev/cxgbe/iw_cxgbe/cq.c
@@ -156,11 +156,10 @@ create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
 			F_FW_RI_RES_WR_IQANDST |
 			V_FW_RI_RES_WR_IQANDSTINDEX(sc->sge.ofld_rxq[0].iq.abs_id));
 	res->u.cq.iqdroprss_to_iqesize = cpu_to_be16(
-			F_FW_RI_RES_WR_IQDROPRSS |
 			V_FW_RI_RES_WR_IQPCIECH(2) |
 			V_FW_RI_RES_WR_IQINTCNTTHRESH(0) |
 			F_FW_RI_RES_WR_IQO |
-			V_FW_RI_RES_WR_IQESIZE(1));
+			V_FW_RI_RES_WR_IQESIZE(ilog2(sizeof *cq->queue) - 4));
 	res->u.cq.iqsize = cpu_to_be16(cq->size);
 	res->u.cq.iqaddr = cpu_to_be64(cq->dma_addr);
 
@@ -715,7 +714,7 @@ skip_cqe:
 static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
 {
 	struct c4iw_qp *qhp = NULL;
-	struct t4_cqe cqe = {0, 0}, *rd_cqe;
+	struct t4_cqe uninitialized_var(cqe), *rd_cqe;
 	struct t4_wq *wq;
 	u32 credit = 0;
 	u8 cqe_flushed;
diff --git a/sys/dev/cxgbe/iw_cxgbe/t4.h b/sys/dev/cxgbe/iw_cxgbe/t4.h
index ffb610420640..cf32c8cc3a65 100644
--- a/sys/dev/cxgbe/iw_cxgbe/t4.h
+++ b/sys/dev/cxgbe/iw_cxgbe/t4.h
@@ -182,7 +182,12 @@ static inline void init_wr_hdr(union t4_wr *wqe, u16 wrid,
 /*
  * CQE defs
  */
+
+/*
+ * 64B CQE entries.
+ */
 struct t4_cqe {
+	struct rss_header rss;
 	__be32 header;
 	__be32 len;
 	union {
@@ -201,7 +206,7 @@ struct t4_cqe {
 		} gen;
 		u64 drain_cookie;
 	} u;
-	__be64 reserved;
+	__be64 reserved[4];
 	__be64 bits_type_ts;
 };
 
diff --git a/sys/dev/cxgbe/iw_cxgbe/user.h b/sys/dev/cxgbe/iw_cxgbe/user.h
index b52c497f12c1..8408f3b6907b 100644
--- a/sys/dev/cxgbe/iw_cxgbe/user.h
+++ b/sys/dev/cxgbe/iw_cxgbe/user.h
@@ -34,7 +34,7 @@
 #ifndef __C4IW_USER_H__
 #define __C4IW_USER_H__
 
-#define C4IW_UVERBS_ABI_VERSION	3
+#define C4IW_UVERBS_ABI_VERSION	5
 
 /*
  * Make sure that all structs defined in this file remain laid out so
@@ -43,6 +43,10 @@
  * In particular do not use pointer types -- pass pointers in __u64
  * instead.
  */
+struct c4iw_create_cq_req {
+	__u64 cqe_size;
+};
+
 struct c4iw_create_cq_resp {
 	__u64 key;
 	__u64 gts_key;