Commit 29ecb19f authored by Jian Shen's avatar Jian Shen Committed by Zheng Zengkai
Browse files

net: hns3: add queue bonding mode support for VF

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



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

For device version V3, the hardware supports queue bonding
mode. VF can not enable queue bond mode unless PF enables it.
So VF needs to query whether PF support queue bonding mode
when initializing, and query whether PF enables queue bonding
mode periodically. For the resource limited, to avoid a VF
occupy to many FD rule space, only trust VF is allowed to enable
queue bonding mode.

Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarJiantao Xiao <xiaojiantao1@h-partners.com>
Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Reviewed-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 3aa7f186
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_VF_UNINIT,            /* (VF -> PF) vf is unintializing */
	HCLGE_MBX_HANDLE_VF_TBL,	/* (VF -> PF) store/clear hw table */
	HCLGE_MBX_GET_RING_VECTOR_MAP,	/* (VF -> PF) get ring-to-vector map */
	HCLGE_MBX_SET_QB = 0x28,        /* (VF -> PF) set queue bonding */
	HCLGE_MBX_PUSH_QB_STATE,        /* (PF -> VF) push qb state */

	HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf flr status */
	HCLGE_MBX_PUSH_LINK_STATUS,	/* (M7 -> PF) get port link status */
@@ -77,6 +79,12 @@ enum hclge_mbx_tbl_cfg_subcode {
	HCLGE_MBX_VPORT_LIST_CLEAR,
};

enum hclge_mbx_qb_cfg_subcode {
	HCLGE_MBX_QB_CHECK_CAPS = 0,	/* query whether support qb */
	HCLGE_MBX_QB_ENABLE,		/* request pf enable qb */
	HCLGE_MBX_QB_GET_STATE		/* query whether qb enabled */
};

#define HCLGE_MBX_MAX_MSG_SIZE	14
#define HCLGE_MBX_MAX_RESP_DATA_SIZE	8U
#define HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM	4
+50 −1
Original line number Diff line number Diff line
@@ -4586,6 +4586,7 @@ static int hclge_sync_pf_qb_mode(struct hclge_dev *hdev)
	struct hnae3_handle *handle = &vport->nic;
	bool request_enable = true;
	int ret;
	u16 i;

	if (!test_and_clear_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state))
		return 0;
@@ -4614,6 +4615,11 @@ static int hclge_sync_pf_qb_mode(struct hclge_dev *hdev)
			clear_bit(HCLGE_STATE_HW_QB_ENABLE, &hdev->state);
			hdev->fd_active_type = HCLGE_FD_RULE_NONE;
		}

		for (i = 1; i < hdev->num_alloc_vport; i++) {
			vport = &hdev->vport[i];
			set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
		}
	} else {
		set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
	}
@@ -4622,10 +4628,33 @@ static int hclge_sync_pf_qb_mode(struct hclge_dev *hdev)
	return ret;
}

static int hclge_sync_vf_qb_mode(struct hclge_vport *vport)
{
	struct hclge_dev *hdev = vport->back;
	bool request_enable = false;
	int ret;

	if (!test_and_clear_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state))
		return 0;

	if (vport->vf_info.trusted && vport->vf_info.request_qb_en &&
	    test_bit(HCLGE_STATE_HW_QB_ENABLE, &hdev->state))
		request_enable = true;

	ret = hclge_set_fd_qb(hdev, vport->vport_id, request_enable);
	if (ret)
		set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
	vport->vf_info.qb_en = request_enable ? 1 : 0;

	return ret;
}

static int hclge_disable_fd_qb_mode(struct hclge_dev *hdev)
{
	struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
	struct hclge_vport *vport;
	int ret;
	u16 i;

	if (!test_bit(HNAE3_DEV_SUPPORT_QB_B, ae_dev->caps) ||
	    !test_bit(HCLGE_STATE_HW_QB_ENABLE, &hdev->state))
@@ -4637,17 +4666,35 @@ static int hclge_disable_fd_qb_mode(struct hclge_dev *hdev)

	clear_bit(HCLGE_STATE_HW_QB_ENABLE, &hdev->state);

	for (i = 1; i < hdev->num_alloc_vport; i++) {
		vport = &hdev->vport[i];
		set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
	}

	return 0;
}

static void hclge_sync_fd_qb_mode(struct hclge_dev *hdev)
{
	struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
	struct hclge_vport *vport;
	int ret;
	u16 i;

	if (!test_bit(HNAE3_DEV_SUPPORT_QB_B, ae_dev->caps))
		return;

	hclge_sync_pf_qb_mode(hdev);
	ret = hclge_sync_pf_qb_mode(hdev);
	if (ret)
		return;

	for (i = 1; i < hdev->num_alloc_vport; i++) {
		vport = &hdev->vport[i];

		ret = hclge_sync_vf_qb_mode(vport);
		if (ret)
			return;
	}
}

static void hclge_periodic_service_task(struct hclge_dev *hdev)
@@ -12269,6 +12316,8 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable)
		return 0;

	vport->vf_info.trusted = new_trusted;

	set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
	set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
	hclge_task_schedule(hdev, 0);

+2 −0
Original line number Diff line number Diff line
@@ -1008,6 +1008,8 @@ struct hclge_vf_info {
	u32 spoofchk;
	u32 max_tx_rate;
	u32 trusted;
	u8 request_qb_en;
	u8 qb_en;
	u8 request_uc_en;
	u8 request_mc_en;
	u8 request_bc_en;
+37 −0
Original line number Diff line number Diff line
@@ -831,6 +831,36 @@ static void hclge_handle_vf_tbl(struct hclge_vport *vport,
	}
}

static void hclge_handle_vf_qb(struct hclge_vport *vport,
			       struct hclge_mbx_vf_to_pf_cmd *mbx_req,
			       struct hclge_respond_to_vf_msg *resp_msg)
{
	struct hclge_dev *hdev = vport->back;

	if (mbx_req->msg.subcode == HCLGE_MBX_QB_CHECK_CAPS) {
		struct hnae3_handle *handle = &hdev->vport[0].nic;

		resp_msg->data[0] = test_bit(HNAE3_PFLAG_FD_QB_ENABLE,
					     &handle->supported_pflags);
		resp_msg->len = sizeof(u8);
	} else if (mbx_req->msg.subcode == HCLGE_MBX_QB_ENABLE) {
		vport->vf_info.request_qb_en = mbx_req->msg.data[0];
		set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state);
	} else if (mbx_req->msg.subcode == HCLGE_MBX_QB_GET_STATE) {
		u16 msg_data = vport->vf_info.qb_en;
		int ret;

		ret = hclge_send_mbx_msg(vport, (u8 *)&msg_data,
					 sizeof(msg_data),
					 HCLGE_MBX_PUSH_QB_STATE,
					 vport->vport_id);
		if (ret)
			dev_err(&hdev->pdev->dev,
				"failed to inform qb state to vport %u, ret = %d\n",
				vport->vport_id, ret);
	}
}

static int
hclge_mbx_map_ring_to_vector_handler(struct hclge_mbx_ops_param *param)
{
@@ -1040,6 +1070,12 @@ static int hclge_mbx_handle_vf_tbl_handler(struct hclge_mbx_ops_param *param)
	return 0;
}

static int hclge_mbx_handle_vf_qb_handler(struct hclge_mbx_ops_param *param)
{
	hclge_handle_vf_qb(param->vport, param->req, param->resp_msg);
	return 0;
}

static const hclge_mbx_ops_fn hclge_mbx_ops_list[HCLGE_MBX_OPCODE_MAX] = {
	[HCLGE_MBX_RESET]   = hclge_mbx_reset_handler,
	[HCLGE_MBX_SET_UNICAST] = hclge_mbx_set_unicast_handler,
@@ -1064,6 +1100,7 @@ static const hclge_mbx_ops_fn hclge_mbx_ops_list[HCLGE_MBX_OPCODE_MAX] = {
	[HCLGE_MBX_VF_UNINIT] = hclge_mbx_vf_uninit_handler,
	[HCLGE_MBX_HANDLE_VF_TBL] = hclge_mbx_handle_vf_tbl_handler,
	[HCLGE_MBX_GET_RING_VECTOR_MAP] = hclge_mbx_get_ring_vector_map_handler,
	[HCLGE_MBX_SET_QB] = hclge_mbx_handle_vf_qb_handler,
	[HCLGE_MBX_GET_VF_FLR_STATUS] = hclge_mbx_get_vf_flr_status_handler,
	[HCLGE_MBX_PUSH_LINK_STATUS] = hclge_mbx_push_link_status_handler,
	[HCLGE_MBX_NCSI_ERROR] = hclge_mbx_ncsi_error_handler,
+74 −0
Original line number Diff line number Diff line
@@ -406,6 +406,74 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
	return 0;
}

static void hclgevf_update_fd_qb_state(struct hclgevf_dev *hdev)
{
	struct hnae3_handle *handle = &hdev->nic;
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	if (!hdev->qb_cfg.pf_support_qb ||
	    !test_bit(HNAE3_PFLAG_FD_QB_ENABLE, &handle->priv_flags))
		return;

	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_QB,
			       HCLGE_MBX_QB_GET_STATE);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
	if (ret)
		dev_err(&hdev->pdev->dev, "failed to get qb state, ret = %d",
			ret);
}

static void hclgevf_get_pf_qb_caps(struct hclgevf_dev *hdev)
{
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
	struct hclge_vf_to_pf_msg send_msg;
	u8 resp_msg;
	int ret;

	if (!test_bit(HNAE3_DEV_SUPPORT_QB_B, ae_dev->caps))
		return;

	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_QB,
			       HCLGE_MBX_QB_CHECK_CAPS);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg,
				   sizeof(resp_msg));
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"failed to get qb caps from PF, ret = %d", ret);
		return;
	}

	hdev->qb_cfg.pf_support_qb = resp_msg > 0;
}

static void hclgevf_set_fd_qb(struct hnae3_handle *handle)
{
#define HCLGEVF_QB_MBX_STATE_OFFSET	0

	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;
	u8 resp_msg;
	int ret;

	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_QB,
			       HCLGE_MBX_QB_ENABLE);
	send_msg.data[HCLGEVF_QB_MBX_STATE_OFFSET] =
		test_bit(HNAE3_PFLAG_FD_QB_ENABLE, &handle->priv_flags) ? 1 : 0;
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg,
				   sizeof(resp_msg));
	if (ret)
		dev_err(&hdev->pdev->dev, "failed to set qb state, ret = %d",
			ret);
}

static bool hclgevf_query_fd_qb_state(struct hnae3_handle *handle)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);

	return hdev->qb_cfg.hw_qb_en;
}

static void hclgevf_request_link_info(struct hclgevf_dev *hdev)
{
	struct hclge_vf_to_pf_msg send_msg;
@@ -1944,6 +2012,8 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev)

	hclgevf_sync_promisc_mode(hdev);

	hclgevf_update_fd_qb_state(hdev);

	hdev->last_serv_processed = jiffies;

out:
@@ -2973,6 +3043,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
		goto err_config;
	}

	hclgevf_get_pf_qb_caps(hdev);

	hclgevf_init_rxd_adv_layout(hdev);

	set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
@@ -3422,6 +3494,8 @@ static const struct hnae3_ae_ops hclgevf_ops = {
	.set_promisc_mode = hclgevf_set_promisc_mode,
	.request_update_promisc_mode = hclgevf_request_update_promisc_mode,
	.get_cmdq_stat = hclgevf_get_cmdq_stat,
	.request_flush_qb_config = hclgevf_set_fd_qb,
	.query_fd_qb_state = hclgevf_query_fd_qb_state,
};

static struct hnae3_ae_algo ae_algovf = {
Loading