]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/hns: Support congestion control algorithm parameter configuration
authorChengchang Tang <tangchengchang@huawei.com>
Thu, 7 May 2026 01:21:48 +0000 (09:21 +0800)
committerLeon Romanovsky <leon@kernel.org>
Mon, 18 May 2026 08:58:41 +0000 (04:58 -0400)
hns RoCE supports 4 congestion control algorithms. Each algorihm
involves multiple parameters. Support configuring these parameters
by debugfs.

Here are some examples of this feature:

* The directory structure:
$ ls /sys/kernel/debug/hns_roce/0000\:35\:00.0/
dcqcn_cc_param  dip_cc_param  hc3_cc_param  ldcp_cc_param
$ ls /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/
ai  al  alp  ashift  cnp_time  f  g  lifespan  max_speed  tkp  tmp

* Read the value of a param:
$ cat /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/ai
1

* Set a new value for a param:
$ echo 2 > /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/ai

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20260507012148.1079712-4-huangjunxian6@hisilicon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/hns/hns_roce_debugfs.c
drivers/infiniband/hw/hns/hns_roce_debugfs.h
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.h

index 724d5ad90bfe34ebf410e9480b8e88fc8e5101ca..05630f7c9155101f682f96852da582804ca7f687 100644 (file)
@@ -3,11 +3,13 @@
  * Copyright (c) 2023 Hisilicon Limited.
  */
 
+#include <linux/cleanup.h>
 #include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/pci.h>
 
 #include "hns_roce_device.h"
+#include "hns_roce_hw_v2.h"
 
 static struct dentry *hns_roce_dbgfs_root;
 
@@ -93,6 +95,250 @@ static void create_sw_stat_debugfs(struct hns_roce_dev *hr_dev,
                            &hns_debugfs_seqfile_fops);
 }
 
+#define __HNS_SCC_ATTR(_name, _type, _offset, _size, _min, _max) {     \
+       .name = _name,                                                  \
+       .algo_type = _type,                                             \
+       .offset = _offset,                                              \
+       .size = _size,                                                  \
+       .min = _min,                                                    \
+       .max = _max,                                                    \
+}
+
+#define HNS_DCQCN_CC_ATTR_RW(_name, NAME)                              \
+       __HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_DCQCN,                  \
+                       HNS_ROCE_DCQCN_##NAME##_OFS,                    \
+                       HNS_ROCE_DCQCN_##NAME##_SZ,                     \
+                       0, HNS_ROCE_DCQCN_##NAME##_MAX)
+
+#define HNS_LDCP_CC_ATTR_RW(_name, NAME)                               \
+       __HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_LDCP,                   \
+                       HNS_ROCE_LDCP_##NAME##_OFS,                     \
+                       HNS_ROCE_LDCP_##NAME##_SZ,                      \
+                       0, HNS_ROCE_LDCP_##NAME##_MAX)
+
+#define HNS_HC3_CC_ATTR_RW(_name, NAME)                                \
+       __HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_HC3,                    \
+                       HNS_ROCE_HC3_##NAME##_OFS,                      \
+                       HNS_ROCE_HC3_##NAME##_SZ,                       \
+                       HNS_ROCE_HC3_##NAME##_MIN,                      \
+                       HNS_ROCE_HC3_##NAME##_MAX)
+
+#define HNS_DIP_CC_ATTR_RW(_name, NAME)                                \
+       __HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_DIP,                    \
+                       HNS_ROCE_DIP_##NAME##_OFS,                      \
+                       HNS_ROCE_DIP_##NAME##_SZ,                       \
+                       0, HNS_ROCE_DIP_##NAME##_MAX)
+
+static const struct hns_roce_cong_attr {
+       enum hns_roce_cong_type cong_type;
+       const char *name;
+       struct hns_roce_cc_param_attr params[HNS_ROCE_CC_PARAM_MAX_NUM];
+} cong_attrs[] = {
+       { CONG_TYPE_DCQCN, "dcqcn_cc_param",
+               {
+                       HNS_DCQCN_CC_ATTR_RW("ai", AI),
+                       HNS_DCQCN_CC_ATTR_RW("f", F),
+                       HNS_DCQCN_CC_ATTR_RW("tkp", TKP),
+                       HNS_DCQCN_CC_ATTR_RW("tmp", TMP),
+                       HNS_DCQCN_CC_ATTR_RW("alp", ALP),
+                       HNS_DCQCN_CC_ATTR_RW("max_speed", MAX_SPEED),
+                       HNS_DCQCN_CC_ATTR_RW("g", G),
+                       HNS_DCQCN_CC_ATTR_RW("al", AL),
+                       HNS_DCQCN_CC_ATTR_RW("cnp_time", CNP_TIME),
+                       HNS_DCQCN_CC_ATTR_RW("ashift", ASHIFT),
+               }
+       },
+       { CONG_TYPE_LDCP, "ldcp_cc_param",
+               {
+                       HNS_LDCP_CC_ATTR_RW("cwd0", CWD0),
+                       HNS_LDCP_CC_ATTR_RW("alpha", ALPHA),
+                       HNS_LDCP_CC_ATTR_RW("gamma", GAMMA),
+                       HNS_LDCP_CC_ATTR_RW("beta", BETA),
+                       HNS_LDCP_CC_ATTR_RW("eta", ETA),
+               }
+       },
+       { CONG_TYPE_HC3, "hc3_cc_param",
+               {
+                       HNS_HC3_CC_ATTR_RW("initial_window", INITIAL_WINDOW),
+                       HNS_HC3_CC_ATTR_RW("bandwidth", BANDWIDTH),
+                       HNS_HC3_CC_ATTR_RW("qlen_shift", QLEN_SHIFT),
+                       HNS_HC3_CC_ATTR_RW("port_usage_shift", PORT_USAGE_SHIFT),
+                       HNS_HC3_CC_ATTR_RW("over_period", OVER_PERIOD),
+                       HNS_HC3_CC_ATTR_RW("max_stage", MAX_STAGE),
+                       HNS_HC3_CC_ATTR_RW("gamma_shift", GAMMA_SHIFT),
+               }
+       },
+       { CONG_TYPE_DIP, "dip_cc_param",
+               {
+                       HNS_DIP_CC_ATTR_RW("ai", AI),
+                       HNS_DIP_CC_ATTR_RW("f", F),
+                       HNS_DIP_CC_ATTR_RW("tkp", TKP),
+                       HNS_DIP_CC_ATTR_RW("tmp", TMP),
+                       HNS_DIP_CC_ATTR_RW("alp", ALP),
+                       HNS_DIP_CC_ATTR_RW("max_speed", MAX_SPEED),
+                       HNS_DIP_CC_ATTR_RW("g", G),
+                       HNS_DIP_CC_ATTR_RW("al", AL),
+                       HNS_DIP_CC_ATTR_RW("cnp_time", CNP_TIME),
+                       HNS_DIP_CC_ATTR_RW("ashift", ASHIFT),
+               }
+       }
+};
+
+static int cc_param_debugfs_show(struct seq_file *file, void *offset)
+{
+       struct hns_cc_param_seqfile *param_seqfile = file->private;
+       const struct hns_roce_cc_param_attr *param_attr = param_seqfile->param_attr;
+       int algo_type = param_attr->algo_type;
+       int index = param_seqfile->index;
+       struct hns_roce_dev *hr_dev =
+               container_of(param_seqfile, struct hns_roce_dev,
+                            dbgfs.cc_param_root[algo_type].params[index]);
+       struct hns_roce_scc_param *scc_param;
+       __le32 val = 0;
+
+       scc_param = &hr_dev->scc_param[algo_type];
+
+       scoped_guard(mutex, &scc_param->scc_mutex) {
+               memcpy(&val,
+                      (void *)scc_param->param + param_attr->offset,
+                      param_attr->size);
+       }
+
+       seq_printf(file, "%u\n", le32_to_cpu(val));
+
+       return 0;
+}
+
+static ssize_t cc_param_debugfs_store(char *buf, size_t count, void *data)
+{
+       struct hns_cc_param_seqfile *param_seqfile = data;
+       const struct hns_roce_cc_param_attr *param_attr = param_seqfile->param_attr;
+       int algo_type = param_attr->algo_type;
+       int index = param_seqfile->index;
+       struct hns_roce_dev *hr_dev =
+               container_of(param_seqfile, struct hns_roce_dev,
+                            dbgfs.cc_param_root[algo_type].params[index]);
+       struct hns_roce_scc_param *scc_param;
+       __le32 attr_val, old_val = 0;
+       u32 val;
+       int ret;
+
+       if (kstrtou32(buf, 0, &val))
+               return -EINVAL;
+
+       if (val > param_attr->max || val < param_attr->min)
+               return -EINVAL;
+
+       attr_val = cpu_to_le32(val);
+       scc_param = &hr_dev->scc_param[algo_type];
+       guard(mutex)(&scc_param->scc_mutex);
+
+       memcpy(&old_val, (void *)scc_param->param + param_attr->offset,
+              param_attr->size);
+       memcpy((void *)scc_param->param + param_attr->offset, &attr_val,
+              param_attr->size);
+
+       ret = hr_dev->hw->config_scc_param(hr_dev, algo_type);
+       if (ret) {
+               memcpy((void *)scc_param->param + param_attr->offset, &old_val,
+                      param_attr->size);
+               return ret;
+       }
+
+       return count;
+}
+
+static void get_default_scc_param(struct hns_roce_dev *hr_dev)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) {
+               ret = hr_dev->hw->query_scc_param(hr_dev, i);
+               if (ret && ret != -EOPNOTSUPP)
+                       ibdev_warn_ratelimited(&hr_dev->ib_dev,
+                                              "failed to get default parameters of scc algo %d, ret = %d.\n",
+                                              i, ret);
+       }
+}
+
+static int hns_roce_alloc_scc_param(struct hns_roce_dev *hr_dev)
+{
+       struct hns_roce_scc_param *scc_param;
+       int i;
+
+       scc_param = kvcalloc(HNS_ROCE_SCC_ALGO_TOTAL, sizeof(*scc_param),
+                            GFP_KERNEL);
+       if (!scc_param)
+               return -ENOMEM;
+
+       for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) {
+               scc_param[i].algo_type = i;
+               scc_param[i].hr_dev = hr_dev;
+               mutex_init(&scc_param[i].scc_mutex);
+       }
+
+       hr_dev->scc_param = scc_param;
+
+       get_default_scc_param(hr_dev);
+
+       return 0;
+}
+
+static void hns_roce_dealloc_scc_param(struct hns_roce_dev *hr_dev)
+{
+       int i;
+
+       if (!hr_dev->scc_param)
+               return;
+
+       for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++)
+               mutex_destroy(&hr_dev->scc_param[i].scc_mutex);
+
+       kvfree(hr_dev->scc_param);
+}
+
+static void create_cc_param_debugfs(struct hns_roce_dev *hr_dev,
+                                   struct dentry *parent)
+{
+       const struct hns_roce_cong_attr *cong_attr;
+       struct hns_cc_param_debugfs *dbgfs;
+       int i, j;
+       int ret;
+
+       if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 ||
+           !(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL) ||
+           hr_dev->is_vf)
+               return;
+
+       ret = hns_roce_alloc_scc_param(hr_dev);
+       if (ret)
+               return;
+
+       for (i = 0; i < CONG_TYPE_MAX_NUM; i++) {
+               cong_attr = &cong_attrs[i];
+               if (!test_bit(cong_attr->cong_type,
+                             (unsigned long *)&hr_dev->caps.cong_cap))
+                       continue;
+
+               dbgfs = &hr_dev->dbgfs.cc_param_root[i];
+               dbgfs->root = debugfs_create_dir(cong_attr->name, parent);
+               for (j = 0; j < HNS_ROCE_CC_PARAM_MAX_NUM; j++) {
+                       if (!cong_attr->params[j].name)
+                               break;
+                       dbgfs->params[j].param_attr = &cong_attr->params[j];
+                       dbgfs->params[j].index = j;
+                       dbgfs->params[j].seqfile.read = cc_param_debugfs_show;
+                       dbgfs->params[j].seqfile.write = cc_param_debugfs_store;
+                       dbgfs->params[j].seqfile.data = &dbgfs->params[j];
+                       debugfs_create_file(cong_attr->params[j].name, 0600,
+                                           dbgfs->root,
+                                           &dbgfs->params[j].seqfile,
+                                           &hns_debugfs_seqfile_fops);
+               }
+       }
+}
+
 /* debugfs for device */
 void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
 {
@@ -102,11 +348,13 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
                                         hns_roce_dbgfs_root);
 
        create_sw_stat_debugfs(hr_dev, dbgfs->root);
+       create_cc_param_debugfs(hr_dev, dbgfs->root);
 }
 
 void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev)
 {
        debugfs_remove_recursive(hr_dev->dbgfs.root);
+       hns_roce_dealloc_scc_param(hr_dev);
 }
 
 /* debugfs for hns module */
index 4e77dea0fbf6cbb0a23c7fcee219ca8e21ffb62f..116b1e8b66772aae2776550010ae5f4a0e2b6581 100644 (file)
@@ -18,10 +18,35 @@ struct hns_sw_stat_debugfs {
        struct hns_debugfs_seqfile sw_stat;
 };
 
+struct hns_roce_cc_param_attr {
+       const char *name;
+       int algo_type;
+       u32 offset;
+       u32 size;
+       u32 max;
+       u32 min;
+};
+
+struct hns_cc_param_seqfile {
+       struct hns_debugfs_seqfile seqfile;
+       const struct hns_roce_cc_param_attr *param_attr;
+       int index;
+};
+
+#define HNS_ROCE_CC_PARAM_MAX_NUM 11
+
+struct hns_cc_param_debugfs {
+       struct dentry *root;
+       struct hns_cc_param_seqfile params[HNS_ROCE_CC_PARAM_MAX_NUM];
+};
+
+#define CONG_TYPE_MAX_NUM 4
+
 /* Debugfs for device */
 struct hns_roce_dev_debugfs {
        struct dentry *root;
        struct hns_sw_stat_debugfs sw_stat_root;
+       struct hns_cc_param_debugfs cc_param_root[CONG_TYPE_MAX_NUM];
 };
 
 struct hns_roce_dev;
index 3f032b8038af0eb45d590fb9f097c01869f553c1..eb7b1865e4c7983c29d7aa98162b93cf03215e29 100644 (file)
@@ -726,6 +726,14 @@ struct hns_roce_eq_table {
        struct hns_roce_eq      *eq;
 };
 
+enum hns_roce_scc_algo {
+       HNS_ROCE_SCC_ALGO_DCQCN = 0,
+       HNS_ROCE_SCC_ALGO_LDCP,
+       HNS_ROCE_SCC_ALGO_HC3,
+       HNS_ROCE_SCC_ALGO_DIP,
+       HNS_ROCE_SCC_ALGO_TOTAL,
+};
+
 struct hns_roce_caps {
        u64             fw_ver;
        u8              num_ports;
@@ -963,6 +971,18 @@ struct hns_roce_hw {
                        u8 *tc_mode, u8 *priority);
        const struct ib_device_ops *hns_roce_dev_ops;
        const struct ib_device_ops *hns_roce_dev_srq_ops;
+       int (*config_scc_param)(struct hns_roce_dev *hr_dev,
+                               enum hns_roce_scc_algo algo);
+       int (*query_scc_param)(struct hns_roce_dev *hr_dev,
+                              enum hns_roce_scc_algo alog);
+};
+
+#define HNS_ROCE_SCC_PARAM_SIZE 4
+struct hns_roce_scc_param {
+       __le32 param[HNS_ROCE_SCC_PARAM_SIZE];
+       enum hns_roce_scc_algo algo_type;
+       struct hns_roce_dev *hr_dev;
+       struct mutex scc_mutex; /* protect @param */
 };
 
 struct hns_roce_dev {
@@ -1026,6 +1046,7 @@ struct hns_roce_dev {
        u64 dwqe_page;
        struct hns_roce_dev_debugfs dbgfs;
        atomic64_t *dfx_cnt;
+       struct hns_roce_scc_param *scc_param;
 };
 
 enum hns_roce_trace_type {
index fa36700d0db2b62215fe39c518df10d9c1d05aa0..0988d91619c19044b026cee331fa930e81307e9c 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/cleanup.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
@@ -7196,6 +7197,57 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
        kfree(eq_table->eq);
 }
 
+static const enum hns_roce_opcode_type scc_opcode[] = {
+       HNS_ROCE_OPC_CFG_DCQCN_PARAM,
+       HNS_ROCE_OPC_CFG_LDCP_PARAM,
+       HNS_ROCE_OPC_CFG_HC3_PARAM,
+       HNS_ROCE_OPC_CFG_DIP_PARAM,
+};
+
+static int hns_roce_v2_config_scc_param(struct hns_roce_dev *hr_dev,
+                                       enum hns_roce_scc_algo algo)
+{
+       struct hns_roce_scc_param *scc_param = &hr_dev->scc_param[algo];
+       struct hns_roce_cmq_desc desc;
+       int ret;
+
+       lockdep_assert_held(&scc_param->scc_mutex);
+
+       hns_roce_cmq_setup_basic_desc(&desc, scc_opcode[algo], false);
+       memcpy(&desc.data, scc_param->param, sizeof(scc_param->param));
+
+       ret = hns_roce_cmq_send(hr_dev, &desc, 1);
+       if (ret)
+               ibdev_err_ratelimited(&hr_dev->ib_dev,
+                                     "failed to configure scc param, opcode: 0x%x, ret = %d.\n",
+                                     le16_to_cpu(desc.opcode), ret);
+
+       return ret;
+}
+
+static int hns_roce_v2_query_scc_param(struct hns_roce_dev *hr_dev,
+                                      enum hns_roce_scc_algo algo)
+{
+       struct hns_roce_scc_param *scc_param;
+       struct hns_roce_cmq_desc desc;
+       int ret;
+
+       hns_roce_cmq_setup_basic_desc(&desc, scc_opcode[algo], true);
+       ret = hns_roce_cmq_send(hr_dev, &desc, 1);
+       if (ret) {
+               ibdev_err_ratelimited(&hr_dev->ib_dev,
+                                     "failed to query scc param, opcode: 0x%x, ret = %d.\n",
+                                     le16_to_cpu(desc.opcode), ret);
+               return ret;
+       }
+
+       scc_param = &hr_dev->scc_param[algo];
+       scoped_guard(mutex, &scc_param->scc_mutex)
+               memcpy(scc_param->param, &desc.data, sizeof(scc_param->param));
+
+       return 0;
+}
+
 static const struct ib_device_ops hns_roce_v2_dev_ops = {
        .destroy_qp = hns_roce_v2_destroy_qp,
        .modify_cq = hns_roce_v2_modify_cq,
@@ -7246,6 +7298,8 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
        .get_dscp = hns_roce_hw_v2_get_dscp,
        .hns_roce_dev_ops = &hns_roce_v2_dev_ops,
        .hns_roce_dev_srq_ops = &hns_roce_v2_dev_srq_ops,
+       .config_scc_param = hns_roce_v2_config_scc_param,
+       .query_scc_param = hns_roce_v2_query_scc_param,
 };
 
 static const struct pci_device_id hns_roce_hw_v2_pci_tbl[] = {
index 285fe0875fac071d72e3ee9116874b823bf47cd7..8c7856aa24dcc3ac6815ad51a2f191874eef4a7f 100644 (file)
@@ -202,6 +202,10 @@ enum {
 /* CMQ command */
 enum hns_roce_opcode_type {
        HNS_QUERY_FW_VER                                = 0x0001,
+       HNS_ROCE_OPC_CFG_DCQCN_PARAM                    = 0x1A80,
+       HNS_ROCE_OPC_CFG_LDCP_PARAM                     = 0x1A81,
+       HNS_ROCE_OPC_CFG_HC3_PARAM                      = 0x1A82,
+       HNS_ROCE_OPC_CFG_DIP_PARAM                      = 0x1A83,
        HNS_ROCE_OPC_QUERY_HW_VER                       = 0x8000,
        HNS_ROCE_OPC_CFG_GLOBAL_PARAM                   = 0x8001,
        HNS_ROCE_OPC_ALLOC_PF_RES                       = 0x8004,
@@ -1459,6 +1463,127 @@ struct hns_roce_wqe_atomic_seg {
        __le64          cmp_data;
 };
 
+#define HNS_ROCE_DCQCN_AI_OFS 0
+#define HNS_ROCE_DCQCN_AI_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_AI_MAX ((u16)(~0U))
+#define HNS_ROCE_DCQCN_F_OFS (HNS_ROCE_DCQCN_AI_OFS + HNS_ROCE_DCQCN_AI_SZ)
+#define HNS_ROCE_DCQCN_F_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_F_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_TKP_OFS (HNS_ROCE_DCQCN_F_OFS + HNS_ROCE_DCQCN_F_SZ)
+#define HNS_ROCE_DCQCN_TKP_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_TKP_MAX 10
+#define HNS_ROCE_DCQCN_TMP_OFS (HNS_ROCE_DCQCN_TKP_OFS + HNS_ROCE_DCQCN_TKP_SZ)
+#define HNS_ROCE_DCQCN_TMP_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_TMP_MAX 15
+#define HNS_ROCE_DCQCN_ALP_OFS (HNS_ROCE_DCQCN_TMP_OFS + HNS_ROCE_DCQCN_TMP_SZ)
+#define HNS_ROCE_DCQCN_ALP_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_ALP_MAX ((u16)(~0U))
+#define HNS_ROCE_DCQCN_MAX_SPEED_OFS (HNS_ROCE_DCQCN_ALP_OFS + \
+                                       HNS_ROCE_DCQCN_ALP_SZ)
+#define HNS_ROCE_DCQCN_MAX_SPEED_SZ sizeof(u32)
+#define HNS_ROCE_DCQCN_MAX_SPEED_MAX ((u32)(~0U))
+#define HNS_ROCE_DCQCN_G_OFS (HNS_ROCE_DCQCN_MAX_SPEED_OFS + \
+                                       HNS_ROCE_DCQCN_MAX_SPEED_SZ)
+#define HNS_ROCE_DCQCN_G_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_G_MAX 15
+#define HNS_ROCE_DCQCN_AL_OFS (HNS_ROCE_DCQCN_G_OFS + HNS_ROCE_DCQCN_G_SZ)
+#define HNS_ROCE_DCQCN_AL_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_AL_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_CNP_TIME_OFS (HNS_ROCE_DCQCN_AL_OFS + \
+                                       HNS_ROCE_DCQCN_AL_SZ)
+#define HNS_ROCE_DCQCN_CNP_TIME_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_CNP_TIME_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_ASHIFT_OFS (HNS_ROCE_DCQCN_CNP_TIME_OFS + \
+                                       HNS_ROCE_DCQCN_CNP_TIME_SZ)
+#define HNS_ROCE_DCQCN_ASHIFT_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_ASHIFT_MAX 15
+
+#define HNS_ROCE_LDCP_CWD0_OFS 0
+#define HNS_ROCE_LDCP_CWD0_SZ sizeof(u32)
+#define HNS_ROCE_LDCP_CWD0_MAX ((u32)(~0U))
+#define HNS_ROCE_LDCP_ALPHA_OFS (HNS_ROCE_LDCP_CWD0_OFS + HNS_ROCE_LDCP_CWD0_SZ)
+#define HNS_ROCE_LDCP_ALPHA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_ALPHA_MAX ((u8)(~0U))
+#define HNS_ROCE_LDCP_GAMMA_OFS (HNS_ROCE_LDCP_ALPHA_OFS + \
+                                       HNS_ROCE_LDCP_ALPHA_SZ)
+#define HNS_ROCE_LDCP_GAMMA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_GAMMA_MAX 7
+#define HNS_ROCE_LDCP_BETA_OFS (HNS_ROCE_LDCP_GAMMA_OFS + \
+                                       HNS_ROCE_LDCP_GAMMA_SZ)
+#define HNS_ROCE_LDCP_BETA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_BETA_MAX 7
+#define HNS_ROCE_LDCP_ETA_OFS (HNS_ROCE_LDCP_BETA_OFS + HNS_ROCE_LDCP_BETA_SZ)
+#define HNS_ROCE_LDCP_ETA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_ETA_MAX 7
+
+#define HNS_ROCE_HC3_INITIAL_WINDOW_OFS 0
+#define HNS_ROCE_HC3_INITIAL_WINDOW_SZ sizeof(u32)
+#define HNS_ROCE_HC3_INITIAL_WINDOW_MIN 0
+#define HNS_ROCE_HC3_INITIAL_WINDOW_MAX ((u32)(~0U))
+#define HNS_ROCE_HC3_BANDWIDTH_OFS (HNS_ROCE_HC3_INITIAL_WINDOW_OFS + \
+                                       HNS_ROCE_HC3_INITIAL_WINDOW_SZ)
+#define HNS_ROCE_HC3_BANDWIDTH_SZ sizeof(u32)
+#define HNS_ROCE_HC3_BANDWIDTH_MIN 1000
+#define HNS_ROCE_HC3_BANDWIDTH_MAX ((u32)(~0U))
+#define HNS_ROCE_HC3_QLEN_SHIFT_OFS (HNS_ROCE_HC3_BANDWIDTH_OFS + \
+                                       HNS_ROCE_HC3_BANDWIDTH_SZ)
+#define HNS_ROCE_HC3_QLEN_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_QLEN_SHIFT_MIN 0
+#define HNS_ROCE_HC3_QLEN_SHIFT_MAX 31
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_OFS (HNS_ROCE_HC3_QLEN_SHIFT_OFS + \
+                                               HNS_ROCE_HC3_QLEN_SHIFT_SZ)
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_MIN 0
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_MAX 100
+#define HNS_ROCE_HC3_OVER_PERIOD_OFS (HNS_ROCE_HC3_PORT_USAGE_SHIFT_OFS + \
+                                       HNS_ROCE_HC3_PORT_USAGE_SHIFT_SZ)
+#define HNS_ROCE_HC3_OVER_PERIOD_SZ sizeof(u8)
+#define HNS_ROCE_HC3_OVER_PERIOD_MIN 0
+#define HNS_ROCE_HC3_OVER_PERIOD_MAX ((u8)(~0U))
+#define HNS_ROCE_HC3_MAX_STAGE_OFS (HNS_ROCE_HC3_OVER_PERIOD_OFS + \
+                                       HNS_ROCE_HC3_OVER_PERIOD_SZ)
+#define HNS_ROCE_HC3_MAX_STAGE_SZ sizeof(u8)
+#define HNS_ROCE_HC3_MAX_STAGE_MIN 0
+#define HNS_ROCE_HC3_MAX_STAGE_MAX ((u8)(~0U))
+#define HNS_ROCE_HC3_GAMMA_SHIFT_OFS (HNS_ROCE_HC3_MAX_STAGE_OFS + \
+                                       HNS_ROCE_HC3_MAX_STAGE_SZ)
+#define HNS_ROCE_HC3_GAMMA_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_GAMMA_SHIFT_MIN 0
+#define HNS_ROCE_HC3_GAMMA_SHIFT_MAX 15
+
+#define HNS_ROCE_DIP_AI_OFS 0
+#define HNS_ROCE_DIP_AI_SZ sizeof(u16)
+#define HNS_ROCE_DIP_AI_MAX ((u16)(~0U))
+#define HNS_ROCE_DIP_F_OFS (HNS_ROCE_DIP_AI_OFS + HNS_ROCE_DIP_AI_SZ)
+#define HNS_ROCE_DIP_F_SZ sizeof(u8)
+#define HNS_ROCE_DIP_F_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_TKP_OFS (HNS_ROCE_DIP_F_OFS + HNS_ROCE_DIP_F_SZ)
+#define HNS_ROCE_DIP_TKP_SZ sizeof(u8)
+#define HNS_ROCE_DIP_TKP_MAX 10
+#define HNS_ROCE_DIP_TMP_OFS (HNS_ROCE_DIP_TKP_OFS + HNS_ROCE_DIP_TKP_SZ)
+#define HNS_ROCE_DIP_TMP_SZ sizeof(u16)
+#define HNS_ROCE_DIP_TMP_MAX 15
+#define HNS_ROCE_DIP_ALP_OFS (HNS_ROCE_DIP_TMP_OFS + HNS_ROCE_DIP_TMP_SZ)
+#define HNS_ROCE_DIP_ALP_SZ sizeof(u16)
+#define HNS_ROCE_DIP_ALP_MAX ((u16)(~0U))
+#define HNS_ROCE_DIP_MAX_SPEED_OFS (HNS_ROCE_DIP_ALP_OFS + HNS_ROCE_DIP_ALP_SZ)
+#define HNS_ROCE_DIP_MAX_SPEED_SZ sizeof(u32)
+#define HNS_ROCE_DIP_MAX_SPEED_MAX ((u32)(~0U))
+#define HNS_ROCE_DIP_G_OFS (HNS_ROCE_DIP_MAX_SPEED_OFS + \
+                               HNS_ROCE_DIP_MAX_SPEED_SZ)
+#define HNS_ROCE_DIP_G_SZ sizeof(u8)
+#define HNS_ROCE_DIP_G_MAX 15
+#define HNS_ROCE_DIP_AL_OFS (HNS_ROCE_DIP_G_OFS + HNS_ROCE_DIP_G_SZ)
+#define HNS_ROCE_DIP_AL_SZ sizeof(u8)
+#define HNS_ROCE_DIP_AL_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_CNP_TIME_OFS (HNS_ROCE_DIP_AL_OFS + HNS_ROCE_DIP_AL_SZ)
+#define HNS_ROCE_DIP_CNP_TIME_SZ sizeof(u8)
+#define HNS_ROCE_DIP_CNP_TIME_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_ASHIFT_OFS (HNS_ROCE_DIP_CNP_TIME_OFS + \
+                                       HNS_ROCE_DIP_CNP_TIME_SZ)
+#define HNS_ROCE_DIP_ASHIFT_SZ sizeof(u8)
+#define HNS_ROCE_DIP_ASHIFT_MAX 15
+
 struct hns_roce_sccc_clr {
        __le32 qpn;
        __le32 rsv[5];