Commit 523f34d8 authored by Chengchang Tang's avatar Chengchang Tang Committed by Zhou Juan
Browse files

RDMA/hns: Support congestion control algorithm parameter configuration

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



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

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>
Reviewed-by: default avatarYangyang Li <liyangyang20@huawei.com>
parent b8dfd735
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ ccflags-y += -I $(srctree)/drivers/net/ethernet/hisilicon/hns3/hns3_common
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_bond.o hns_roce_dca.o hns_roce_debugfs.o
	hns_roce_bond.o hns_roce_dca.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)
+38 −4
Original line number Diff line number Diff line
@@ -767,11 +767,19 @@ 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,
	CONG_TYPE_HC3,
	CONG_TYPE_DIP,
	CONG_TYPE_DCQCN = 1 << HNS_ROCE_SCC_ALGO_DCQCN,
	CONG_TYPE_LDCP = 1 << HNS_ROCE_SCC_ALGO_LDCP,
	CONG_TYPE_HC3 = 1 << HNS_ROCE_SCC_ALGO_HC3,
	CONG_TYPE_DIP = 1 << HNS_ROCE_SCC_ALGO_DIP,
};

struct hns_roce_caps {
@@ -1016,6 +1024,28 @@ struct hns_roce_hw {
	int (*bond_init)(struct hns_roce_dev *hr_dev);
	bool (*bond_is_active)(struct hns_roce_dev *hr_dev);
	struct net_device *(*get_bond_netdev)(struct hns_roce_dev *hr_dev);
	int (*config_scc_param)(struct hns_roce_dev *hr_dev, u8 port_num,
				enum hns_roce_scc_algo algo);
	int (*query_scc_param)(struct hns_roce_dev *hr_dev, u8 port_num,
			       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;
	u8 port_num;
};

struct hns_roce_port {
	struct hns_roce_dev *hr_dev;
	u8 port_num;
	struct kobject kobj;
	struct hns_roce_scc_param *scc_param;
};

struct hns_roce_dev {
@@ -1094,6 +1124,7 @@ struct hns_roce_dev {
	struct delayed_work bond_work;
	struct hns_roce_bond_group *bond_grp;
	struct netdev_lag_lower_state_info slave_state;
	struct hns_roce_port port_data[HNS_ROCE_MAX_PORTS];
	atomic64_t *dfx_cnt;
};

@@ -1379,4 +1410,7 @@ 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);
int hns_roce_create_port_files(struct ib_device *ibdev, u8 port_num,
			       struct kobject *kobj);
void hns_roce_unregister_sysfs(struct hns_roce_dev *hr_dev);
#endif /* _HNS_ROCE_DEVICE_H */
+77 −0
Original line number Diff line number Diff line
@@ -7146,6 +7146,81 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
	kfree(eq_table->eq);
}

static 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,
					u8 port_num,
					enum hns_roce_scc_algo algo)
{
	struct hns_roce_scc_param *scc_param;
	struct hns_roce_cmq_desc desc;
	struct hns_roce_port *pdata;
	int ret;

	if (port_num > hr_dev->caps.num_ports) {
		ibdev_err_ratelimited(&hr_dev->ib_dev,
				      "invalid port num %u.\n", port_num);
		return -ENODEV;
	}

	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);
	pdata = &hr_dev->port_data[port_num - 1];
	scc_param = &pdata->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,
				       u8 port_num, enum hns_roce_scc_algo algo)
{
	struct hns_roce_scc_param *scc_param;
	struct hns_roce_cmq_desc desc;
	struct hns_roce_port *pdata;
	int ret;

	if (port_num > hr_dev->caps.num_ports) {
		ibdev_err_ratelimited(&hr_dev->ib_dev,
				      "invalid port num %u.\n", port_num);
		return -ENODEV;
	}

	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;
	}

	pdata = &hr_dev->port_data[port_num - 1];
	scc_param = &pdata->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,
@@ -7198,6 +7273,8 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
	.bond_is_active = hns_roce_bond_is_active,
	.get_bond_netdev = hns_roce_get_bond_netdev,
	.query_hw_counter = hns_roce_hw_v2_query_counter,
	.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
@@ -227,6 +227,10 @@ enum {
enum hns_roce_opcode_type {
	HNS_QUERY_FW_VER				= 0x0001,
	HNS_QUERY_MAC_TYPE				= 0x0389,
	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,
@@ -1468,6 +1472,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];
+2 −0
Original line number Diff line number Diff line
@@ -870,6 +870,7 @@ static const struct ib_device_ops hns_roce_dev_ops = {
	.reg_user_mr = hns_roce_reg_user_mr,
	.alloc_hw_stats = hns_roce_alloc_hw_port_stats,
	.get_hw_stats = hns_roce_get_hw_stats,
	.init_port = hns_roce_create_port_files,

	INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah),
	INIT_RDMA_OBJ_SIZE(ib_cq, hns_roce_cq, ib_cq),
@@ -1441,6 +1442,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_device(hr_dev);
	hns_roce_unregister_debugfs(hr_dev);

Loading