Commit 41da9cd8 authored by Chengchang Tang's avatar Chengchang Tang Committed by Juan Zhou
Browse files

RDMA/hns: Support congestion control algorithm parameter configuration

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I95PFR



----------------------------------------------------------------------

hns roce support 4 congestion control algorithms. Each algorihm
involves multiple parameters. This patch add port sysfs directory
for each algorithm, which allows users to modify the parameters
of these algorithms.

Signed-off-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarJuan Zhou <zhoujuan51@h-partners.com>
parent dab8c5b9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ ccflags-y := -I $(srctree)/drivers/net/ethernet/hisilicon/hns3
hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
	hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \
	hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o \
	hns_roce_debugfs.o
	hns_roce_debugfs.o hns_roce_sysfs.o

ifdef CONFIG_INFINIBAND_HNS_HIP08
hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
+27 −0
Original line number Diff line number Diff line
@@ -710,6 +710,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,
};

enum cong_type {
	CONG_TYPE_DCQCN,
	CONG_TYPE_LDCP,
@@ -954,6 +962,20 @@ struct hns_roce_hw {
				u64 *stats, u32 port, int *hw_counters);
	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];
	u32 lifespan;
	unsigned long timestamp;
	enum hns_roce_scc_algo algo_type;
	struct delayed_work scc_cfg_dwork;
	struct hns_roce_dev *hr_dev;
};

struct hns_roce_dev {
@@ -1019,6 +1041,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;
};

static inline struct hns_roce_dev *to_hr_dev(struct ib_device *ib_dev)
@@ -1154,6 +1177,8 @@ static inline u8 get_tclass(const struct ib_global_route *grh)
	       grh->traffic_class >> DSCP_SHIFT : grh->traffic_class;
}

extern const struct attribute_group *hns_attr_port_groups[];

void hns_roce_init_uar_table(struct hns_roce_dev *dev);
int hns_roce_uar_alloc(struct hns_roce_dev *dev, struct hns_roce_uar *uar);

@@ -1294,4 +1319,6 @@ struct hns_user_mmap_entry *
hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address,
				size_t length,
				enum hns_roce_mmap_type mmap_type);
void hns_roce_register_sysfs(struct hns_roce_dev *hr_dev);
void hns_roce_unregister_sysfs(struct hns_roce_dev *hr_dev);
#endif /* _HNS_ROCE_DEVICE_H */
+63 −0
Original line number Diff line number Diff line
@@ -6733,6 +6733,67 @@ 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;
	struct hns_roce_cmq_desc desc;
	int ret;

	if (algo >= HNS_ROCE_SCC_ALGO_TOTAL) {
		ibdev_err_ratelimited(&hr_dev->ib_dev, "invalid SCC algo.\n");
		return -EINVAL;
	}

	hns_roce_cmq_setup_basic_desc(&desc, scc_opcode[algo], false);
	scc_param = &hr_dev->scc_param[algo];
	memcpy(&desc.data, scc_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;

	if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 || hr_dev->is_vf)
		return -EOPNOTSUPP;

	if (algo >= HNS_ROCE_SCC_ALGO_TOTAL) {
		ibdev_err_ratelimited(&hr_dev->ib_dev, "invalid SCC algo.\n");
		return -EINVAL;
	}

	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];
	memcpy(scc_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,
@@ -6782,6 +6843,8 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
	.query_hw_counter = hns_roce_hw_v2_query_counter,
	.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[] = {
+132 −0
Original line number Diff line number Diff line
@@ -195,6 +195,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,
@@ -1428,6 +1432,134 @@ 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 15
#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_DCQCN_LIFESPAN_OFS (HNS_ROCE_DCQCN_ASHIFT_OFS + \
					HNS_ROCE_DCQCN_ASHIFT_SZ)
#define HNS_ROCE_DCQCN_LIFESPAN_SZ sizeof(u32)
#define HNS_ROCE_DCQCN_LIFESPAN_MAX 1000

#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 ((u8)(~0U))
#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 ((u8)(~0U))
#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 ((u8)(~0U))
#define HNS_ROCE_LDCP_LIFESPAN_OFS (4 * sizeof(u32))
#define HNS_ROCE_LDCP_LIFESPAN_SZ sizeof(u32)
#define HNS_ROCE_LDCP_LIFESPAN_MAX 1000

#define HNS_ROCE_HC3_INITIAL_WINDOW_OFS 0
#define HNS_ROCE_HC3_INITIAL_WINDOW_SZ sizeof(u32)
#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_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_MAX ((u8)(~0U))
#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_MAX ((u8)(~0U))
#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_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_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_MAX 15
#define HNS_ROCE_HC3_LIFESPAN_OFS (4 * sizeof(u32))
#define HNS_ROCE_HC3_LIFESPAN_SZ sizeof(u32)
#define HNS_ROCE_HC3_LIFESPAN_MAX 1000

#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 15
#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
#define HNS_ROCE_DIP_LIFESPAN_OFS (HNS_ROCE_DIP_ASHIFT_OFS + \
					HNS_ROCE_DIP_ASHIFT_SZ)
#define HNS_ROCE_DIP_LIFESPAN_SZ sizeof(u32)
#define HNS_ROCE_DIP_LIFESPAN_MAX 1000

struct hns_roce_sccc_clr {
	__le32 qpn;
	__le32 rsv[5];
+3 −0
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ static const struct ib_device_ops hns_roce_dev_ops = {
	.query_pkey = hns_roce_query_pkey,
	.query_port = hns_roce_query_port,
	.reg_user_mr = hns_roce_reg_user_mr,
	.port_groups = hns_attr_port_groups,

	INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah),
	INIT_RDMA_OBJ_SIZE(ib_cq, hns_roce_cq, ib_cq),
@@ -1106,6 +1107,7 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
	if (ret)
		goto error_failed_register_device;

	hns_roce_register_sysfs(hr_dev);
	hns_roce_register_debugfs(hr_dev);

	return 0;
@@ -1140,6 +1142,7 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)

void hns_roce_exit(struct hns_roce_dev *hr_dev)
{
	hns_roce_unregister_sysfs(hr_dev);
	hns_roce_unregister_debugfs(hr_dev);
	hns_roce_unregister_device(hr_dev);

Loading