git: 5096c87b4435 - main - IB/mlx5: Add support for CQE compressing

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 16 Sep 2026 14:12:43 UTC
The branch main has been updated by kib:

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

commit 5096c87b4435657c471b6d5ba86b4c4ee15f252b
Author:     Vag Singh <vag.singh@oneconvergence.com>
AuthorDate: 2025-08-12 03:07:38 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-16 14:12:06 +0000

    IB/mlx5: Add support for CQE compressing
    
    [PATCH 06/31] FreeBSD OFED support for DPDK MLX5 PMD
    
    CQE compressing reduces PCI overhead by coalescing and compressing
    multiple CQEs into a single merged CQE. Successful compressing
    improves message rate especially for small packet traffic.
    
    CQE compressing is supported for all 64B CQE formats (with certain
    limitations) generated by RQ/Responder or by SQ/Requestor.
    
    IB/mlx5: Report mlx5 CQE compression capabilities when querying device
    The capabilities include:
     - Max number of compressed and aggregated CQEs in a single session,
       while zero means unsupported.
     - For Responder, there are two formats of mini CQE: mini CQE with Rx
       hash and mini CQE with checksum. They're mutual exclusive.
    
    Differential revision:  https://reviews.freebsd.org/D32180
    MFC after:      1 month
---
 sys/dev/mlx5/mlx5_en/mlx5_en_main.c   |  2 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c     | 25 +++++++++++++++++++++++++
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c   | 10 ++++++++++
 sys/dev/mlx5/mlx5_ifc.h               |  2 +-
 sys/ofed/include/uapi/rdma/mlx5-abi.h | 13 +++++++++++++
 5 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index ed1b59da1049..4d94ddf6a391 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -2460,7 +2460,7 @@ mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
 	 */
 	if (priv->params.cqe_zipping_en) {
 		MLX5_SET(cqc, cqc, mini_cqe_res_format, MLX5_CQE_FORMAT_HASH);
-		MLX5_SET(cqc, cqc, cqe_compression_en, 1);
+		MLX5_SET(cqc, cqc, cqe_comp_en, 1);
 	}
 
 	MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_rq_size);
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
index 28fcc7b648e5..213b8705b6f3 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
@@ -814,6 +814,31 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
 		*index = context->bfregi.sys_pages[0];
 	}
 
+	if (ucmd.cqe_comp_en == 1) {
+		if (unlikely((*cqe_size != 64) ||
+			     !MLX5_CAP_GEN(dev->mdev, cqe_compression))) {
+			err = -EOPNOTSUPP;
+			mlx5_ib_warn(dev, "CQE compression is not supported for size %d!\n",
+				     *cqe_size);
+			goto err_cqb;
+		}
+
+		if (unlikely(!ucmd.cqe_comp_res_format ||
+			     !(ucmd.cqe_comp_res_format <
+			       MLX5_IB_CQE_RES_RESERVED) ||
+			     (ucmd.cqe_comp_res_format &
+			      (ucmd.cqe_comp_res_format - 1)))) {
+			err = -EOPNOTSUPP;
+			mlx5_ib_warn(dev, "CQE compression res format %d is not supported!\n",
+				     ucmd.cqe_comp_res_format);
+			goto err_cqb;
+		}
+
+		MLX5_SET(cqc, cqc, cqe_comp_en, 1);
+		MLX5_SET(cqc, cqc, mini_cqe_res_format,
+			 ilog2(ucmd.cqe_comp_res_format));
+	}
+
 	MLX5_SET(create_cq_in, *cqb, uid, context->devx_uid);
 	return 0;
 
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index b959e0d92a83..aa010a4c88bc 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -818,6 +818,16 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
 			1 << MLX5_CAP_GEN(dev->mdev, log_max_rq);
 	}
 
+	if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) {
+		resp.cqe_comp_caps.max_num =
+			MLX5_CAP_GEN(dev->mdev, cqe_compression) ?
+			MLX5_CAP_GEN(dev->mdev, cqe_compression_max_num) : 0;
+		resp.cqe_comp_caps.supported_format =
+			MLX5_IB_CQE_RES_FORMAT_HASH |
+			MLX5_IB_CQE_RES_FORMAT_CSUM;
+		resp.response_length += sizeof(resp.cqe_comp_caps);
+	}
+
 	if (uhw->outlen) {
 		err = ib_copy_to_udata(uhw, &resp, resp.response_length);
 
diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h
index 1906b670f013..a42fd920dc6c 100644
--- a/sys/dev/mlx5/mlx5_ifc.h
+++ b/sys/dev/mlx5/mlx5_ifc.h
@@ -3482,7 +3482,7 @@ struct mlx5_ifc_cqc_bits {
 	u8         scqe_break_moderation_en[0x1];
 	u8         oi[0x1];
 	u8         cq_period_mode[0x2];
-	u8         cqe_compression_en[0x1];
+	u8         cqe_comp_en[0x1];
 	u8         mini_cqe_res_format[0x2];
 	u8         st[0x4];
 	u8         reserved_2[0x8];
diff --git a/sys/ofed/include/uapi/rdma/mlx5-abi.h b/sys/ofed/include/uapi/rdma/mlx5-abi.h
index 91af500c9a61..52d6f061970a 100644
--- a/sys/ofed/include/uapi/rdma/mlx5-abi.h
+++ b/sys/ofed/include/uapi/rdma/mlx5-abi.h
@@ -145,11 +145,24 @@ struct mlx5_ib_rss_caps {
 	__u8 reserved[7];
 };
 
+enum mlx5_ib_cqe_comp_res_format {
+	MLX5_IB_CQE_RES_FORMAT_HASH	= 1 << 0,
+	MLX5_IB_CQE_RES_FORMAT_CSUM	= 1 << 1,
+	MLX5_IB_CQE_RES_RESERVED	= 1 << 2,
+};
+
+struct mlx5_ib_cqe_comp_caps {
+	__u32 max_num;
+	__u32 supported_format; /* enum mlx5_ib_cqe_comp_res_format */
+};
+
+
 struct mlx5_ib_query_device_resp {
 	__u32	comp_mask;
 	__u32	response_length;
 	struct	mlx5_ib_tso_caps tso_caps;
 	struct	mlx5_ib_rss_caps rss_caps;
+	struct	mlx5_ib_cqe_comp_caps cqe_comp_caps;
 };
 
 enum mlx5_ib_create_cq_flags {