Commit de24ed30 authored by Jian Shen's avatar Jian Shen Committed by Hao Chen
Browse files

net: hns3: add ieee_setmaxrate and ieee_getmaxrate support for pf

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


CVE: NA

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

Add support for ieee_setmaxrate and ieee_getmaxrate. The minimum
rate supported by the hardware is 1 Mbit/s.

Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHao Lan <lanhao@huawei.com>
parent 47f16eba
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -879,6 +879,10 @@ struct hnae3_dcb_ops {
	int (*ieee_setpfc)(struct hnae3_handle *, struct ieee_pfc *);
	int (*ieee_setapp)(struct hnae3_handle *h, struct dcb_app *app);
	int (*ieee_delapp)(struct hnae3_handle *h, struct dcb_app *app);
	int (*ieee_setmaxrate)(struct hnae3_handle *h,
			       struct ieee_maxrate *maxrate);
	int (*ieee_getmaxrate)(struct hnae3_handle *h,
			       struct ieee_maxrate *maxrate);

	/* DCBX configuration */
	u8   (*getdcbx)(struct hnae3_handle *);
+26 −0
Original line number Diff line number Diff line
@@ -104,6 +104,28 @@ static u8 hns3_dcbnl_setdcbx(struct net_device *ndev, u8 mode)
	return 1;
}

static int hns3_dcbnl_ieee_setmaxrate(struct net_device *netdev,
				      struct ieee_maxrate *maxrate)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	if (h->kinfo.dcb_ops->ieee_setmaxrate)
		return h->kinfo.dcb_ops->ieee_setmaxrate(h, maxrate);

	return -EOPNOTSUPP;
}

static int hns3_dcbnl_ieee_getmaxrate(struct net_device *netdev,
				      struct ieee_maxrate *maxrate)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	if (h->kinfo.dcb_ops->ieee_getmaxrate)
		return h->kinfo.dcb_ops->ieee_getmaxrate(h, maxrate);

	return -EOPNOTSUPP;
}

static const struct dcbnl_rtnl_ops hns3_dcbnl_ops = {
	.ieee_getets	= hns3_dcbnl_ieee_getets,
	.ieee_setets	= hns3_dcbnl_ieee_setets,
@@ -111,6 +133,8 @@ static const struct dcbnl_rtnl_ops hns3_dcbnl_ops = {
	.ieee_setpfc	= hns3_dcbnl_ieee_setpfc,
	.ieee_setapp    = hns3_dcbnl_ieee_setapp,
	.ieee_delapp    = hns3_dcbnl_ieee_delapp,
	.ieee_setmaxrate    = hns3_dcbnl_ieee_setmaxrate,
	.ieee_getmaxrate    = hns3_dcbnl_ieee_getmaxrate,
	.getdcbx	= hns3_dcbnl_getdcbx,
	.setdcbx	= hns3_dcbnl_setdcbx,
};
@@ -120,6 +144,8 @@ static const struct dcbnl_rtnl_ops hns3_unic_dcbnl_ops = {
	.ieee_setets	= hns3_dcbnl_ieee_setets,
	.ieee_setapp	= hns3_dcbnl_ieee_setapp,
	.ieee_delapp	= hns3_dcbnl_ieee_delapp,
	.ieee_setmaxrate    = hns3_dcbnl_ieee_setmaxrate,
	.ieee_getmaxrate    = hns3_dcbnl_ieee_getmaxrate,
	.getdcbx	= hns3_dcbnl_getdcbx,
	.setdcbx	= hns3_dcbnl_setdcbx,
};
+68 −0
Original line number Diff line number Diff line
@@ -509,6 +509,72 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
	return 0;
}

static int hclge_ieee_getmaxrate(struct hnae3_handle *h,
				 struct ieee_maxrate *maxrate)
{
	struct hnae3_tc_info *tc_info = &h->kinfo.tc_info;
	struct hclge_vport *vport = hclge_get_vport(h);
	struct hclge_dev *hdev = vport->back;

	if (!hnae3_dev_roh_supported(hdev) &&
	    !hnae3_dev_ubl_supported(hdev->ae_dev))
		return -EOPNOTSUPP;

	memcpy(maxrate, tc_info->max_rate, sizeof(struct ieee_maxrate));
	return 0;
}

static int hclge_check_maxrate(struct hclge_dev *hdev,
			       struct ieee_maxrate *maxrate)
{
	u64 max_speed = (u64)hdev->hw.mac.max_speed * TM_RATE_PORT_RATE_SCALE;
	u8 i;

	for (i = 0; i < HNAE3_MAX_TC; i++) {
		/* no limit */
		if (!maxrate->tc_maxrate[i])
			continue;
		if (maxrate->tc_maxrate[i] < TM_RATE_PORT_RATE_SCALE ||
		    maxrate->tc_maxrate[i] > max_speed) {
			dev_err(&hdev->pdev->dev,
				"invalid max_rate[%llubps]: the range is [1Mbps, %uMbps]\n",
				maxrate->tc_maxrate[i] * HCLGE_BYTE_BITS,
				hdev->hw.mac.max_speed);
			return -EINVAL;
		}
	}
	return 0;
}

static int hclge_ieee_setmaxrate(struct hnae3_handle *h,
				 struct ieee_maxrate *maxrate)
{
	struct hnae3_tc_info *tc_info = &h->kinfo.tc_info;
	struct hclge_vport *vport = hclge_get_vport(h);
	struct hclge_dev *hdev = vport->back;
	struct hnae3_tc_info old_tc_info;
	int ret;

	if (!hnae3_dev_roh_supported(hdev) &&
	    !hnae3_dev_ubl_supported(hdev->ae_dev))
		return -EOPNOTSUPP;

	if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) || tc_info->mqprio_active)
		return -EINVAL;

	ret = hclge_check_maxrate(hdev, maxrate);
	if (ret)
		return ret;

	memcpy(&old_tc_info, tc_info, sizeof(struct hnae3_tc_info));
	memcpy(tc_info->max_rate, maxrate, sizeof(struct ieee_maxrate));
	ret = hclge_tm_set_tc_rate_limit(hdev, tc_info);
	if (ret)
		memcpy(tc_info, &old_tc_info, sizeof(struct hnae3_tc_info));

	return ret;
}

static int hclge_mqprio_qopt_check_rate(struct hclge_dev *hdev, u64 min_rate,
					u64 max_rate)
{
@@ -701,6 +767,8 @@ static const struct hnae3_dcb_ops hns3_dcb_ops = {
	.getdcbx	= hclge_getdcbx,
	.setdcbx	= hclge_setdcbx,
	.setup_tc	= hclge_setup_tc,
	.ieee_setmaxrate = hclge_ieee_setmaxrate,
	.ieee_getmaxrate = hclge_ieee_getmaxrate,
};

void hclge_dcb_ops_set(struct hclge_dev *hdev)
+3 −0
Original line number Diff line number Diff line
@@ -12,4 +12,7 @@ void hclge_dcb_ops_set(struct hclge_dev *hdev);
static inline void hclge_dcb_ops_set(struct hclge_dev *hdev) {}
#endif

#define HCLGE_BYTE_BITS		8ULL
#define HCLGE_RATE_UNIT_MBPS	1000000ULL /* 1Mbps */

#endif /* __HCLGE_DCB_H__ */