Commit fe1f4fc1 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-hns3-add-three-optimizations-for-mailbox-handling'



Huazhong Tan says:

====================
net: hns3: add three optimizations for mailbox handling

This patchset includes three code optimizations for mailbox handling.

[patch 1] adds a response code conversion.
[patch 2] refactors some structure definitions about PF and
VF mailbox.
[patch 3] refactors the condition whether PF responds VF's mailbox.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 09984483 bb5790b7
Loading
Loading
Loading
Loading
+46 −8
Original line number Diff line number Diff line
@@ -7,8 +7,6 @@
#include <linux/mutex.h>
#include <linux/types.h>

#define HCLGE_MBX_VF_MSG_DATA_NUM	16

enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_RESET = 0x01,		/* (VF -> PF) assert reset */
	HCLGE_MBX_ASSERTING_RESET,	/* (PF -> VF) PF is asserting reset*/
@@ -72,10 +70,15 @@ enum hclge_mbx_vlan_cfg_subcode {
	HCLGE_MBX_GET_PORT_BASE_VLAN_STATE,	/* get port based vlan state */
};

#define HCLGE_MBX_MAX_MSG_SIZE	16
#define HCLGE_MBX_MAX_MSG_SIZE	14
#define HCLGE_MBX_MAX_RESP_DATA_SIZE	8U
#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM	3
#define HCLGE_MBX_RING_NODE_VARIABLE_NUM	3
#define HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM	4

struct hclge_ring_chain_param {
	u8 ring_type;
	u8 tqp_index;
	u8 int_gl_index;
};

struct hclgevf_mbx_resp_status {
	struct mutex mbx_mutex; /* protects against contending sync cmd resp */
@@ -85,6 +88,41 @@ struct hclgevf_mbx_resp_status {
	u8 additional_info[HCLGE_MBX_MAX_RESP_DATA_SIZE];
};

struct hclge_respond_to_vf_msg {
	int status;
	u8 data[HCLGE_MBX_MAX_RESP_DATA_SIZE];
	u16 len;
};

struct hclge_vf_to_pf_msg {
	u8 code;
	union {
		struct {
			u8 subcode;
			u8 data[HCLGE_MBX_MAX_MSG_SIZE];
		};
		struct {
			u8 en_bc;
			u8 en_uc;
			u8 en_mc;
		};
		struct {
			u8 vector_id;
			u8 ring_num;
			struct hclge_ring_chain_param
				param[HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM];
		};
	};
};

struct hclge_pf_to_vf_msg {
	u16 code;
	u16 vf_mbx_msg_code;
	u16 vf_mbx_msg_subcode;
	u16 resp_status;
	u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE];
};

struct hclge_mbx_vf_to_pf_cmd {
	u8 rsv;
	u8 mbx_src_vfid; /* Auto filled by IMP */
@@ -92,17 +130,17 @@ struct hclge_mbx_vf_to_pf_cmd {
	u8 rsv1[1];
	u8 msg_len;
	u8 rsv2[3];
	u8 msg[HCLGE_MBX_MAX_MSG_SIZE];
	struct hclge_vf_to_pf_msg msg;
};

#define HCLGE_MBX_NEED_RESP_BIT		BIT(0)
#define HCLGE_MBX_NEED_RESP_B		0

struct hclge_mbx_pf_to_vf_cmd {
	u8 dest_vfid;
	u8 rsv[3];
	u8 msg_len;
	u8 rsv1[3];
	u16 msg[8];
	struct hclge_pf_to_vf_msg msg;
};

struct hclge_vf_rst_cmd {
+175 −212

File changed.

Preview size limit exceeded, changes collapsed.

+170 −141
Original line number Diff line number Diff line
@@ -229,13 +229,25 @@ static void hclgevf_get_stats(struct hnae3_handle *handle, u64 *data)
	hclgevf_tqps_get_stats(handle, data);
}

static void hclgevf_build_send_msg(struct hclge_vf_to_pf_msg *msg, u8 code,
				   u8 subcode)
{
	if (msg) {
		memset(msg, 0, sizeof(struct hclge_vf_to_pf_msg));
		msg->code = code;
		msg->subcode = subcode;
	}
}

static int hclgevf_get_tc_info(struct hclgevf_dev *hdev)
{
	struct hclge_vf_to_pf_msg send_msg;
	u8 resp_msg;
	int status;

	status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_TCINFO, 0, NULL, 0,
				      true, &resp_msg, sizeof(resp_msg));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_TCINFO, 0);
	status = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg,
				      sizeof(resp_msg));
	if (status) {
		dev_err(&hdev->pdev->dev,
			"VF request to get TC info from PF failed %d",
@@ -251,12 +263,14 @@ static int hclgevf_get_tc_info(struct hclgevf_dev *hdev)
static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev)
{
	struct hnae3_handle *nic = &hdev->nic;
	struct hclge_vf_to_pf_msg send_msg;
	u8 resp_msg;
	int ret;

	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
				   HCLGE_MBX_GET_PORT_BASE_VLAN_STATE,
				   NULL, 0, true, &resp_msg, sizeof(u8));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
			       HCLGE_MBX_GET_PORT_BASE_VLAN_STATE);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg,
				   sizeof(u8));
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"VF request to get port based vlan state failed %d",
@@ -272,11 +286,16 @@ static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev)
static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
{
#define HCLGEVF_TQPS_RSS_INFO_LEN	6
#define HCLGEVF_TQPS_ALLOC_OFFSET	0
#define HCLGEVF_TQPS_RSS_SIZE_OFFSET	2
#define HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET	4

	u8 resp_msg[HCLGEVF_TQPS_RSS_INFO_LEN];
	struct hclge_vf_to_pf_msg send_msg;
	int status;

	status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QINFO, 0, NULL, 0,
				      true, resp_msg,
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QINFO, 0);
	status = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg,
				      HCLGEVF_TQPS_RSS_INFO_LEN);
	if (status) {
		dev_err(&hdev->pdev->dev,
@@ -285,9 +304,12 @@ static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
		return status;
	}

	memcpy(&hdev->num_tqps, &resp_msg[0], sizeof(u16));
	memcpy(&hdev->rss_size_max, &resp_msg[2], sizeof(u16));
	memcpy(&hdev->rx_buf_len, &resp_msg[4], sizeof(u16));
	memcpy(&hdev->num_tqps, &resp_msg[HCLGEVF_TQPS_ALLOC_OFFSET],
	       sizeof(u16));
	memcpy(&hdev->rss_size_max, &resp_msg[HCLGEVF_TQPS_RSS_SIZE_OFFSET],
	       sizeof(u16));
	memcpy(&hdev->rx_buf_len, &resp_msg[HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET],
	       sizeof(u16));

	return 0;
}
@@ -295,11 +317,15 @@ static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev)
{
#define HCLGEVF_TQPS_DEPTH_INFO_LEN	4
#define HCLGEVF_TQPS_NUM_TX_DESC_OFFSET	0
#define HCLGEVF_TQPS_NUM_RX_DESC_OFFSET	2

	u8 resp_msg[HCLGEVF_TQPS_DEPTH_INFO_LEN];
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QDEPTH, 0, NULL, 0,
				   true, resp_msg,
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QDEPTH, 0);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg,
				   HCLGEVF_TQPS_DEPTH_INFO_LEN);
	if (ret) {
		dev_err(&hdev->pdev->dev,
@@ -308,8 +334,10 @@ static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev)
		return ret;
	}

	memcpy(&hdev->num_tx_desc, &resp_msg[0], sizeof(u16));
	memcpy(&hdev->num_rx_desc, &resp_msg[2], sizeof(u16));
	memcpy(&hdev->num_tx_desc, &resp_msg[HCLGEVF_TQPS_NUM_TX_DESC_OFFSET],
	       sizeof(u16));
	memcpy(&hdev->num_rx_desc, &resp_msg[HCLGEVF_TQPS_NUM_RX_DESC_OFFSET],
	       sizeof(u16));

	return 0;
}
@@ -317,14 +345,14 @@ static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev)
static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 msg_data[2], resp_data[2];
	struct hclge_vf_to_pf_msg send_msg;
	u16 qid_in_pf = 0;
	u8 resp_data[2];
	int ret;

	memcpy(&msg_data[0], &queue_id, sizeof(queue_id));

	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QID_IN_PF, 0, msg_data,
				   sizeof(msg_data), true, resp_data,
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QID_IN_PF, 0);
	memcpy(send_msg.data, &queue_id, sizeof(queue_id));
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_data,
				   sizeof(resp_data));
	if (!ret)
		qid_in_pf = *(u16 *)resp_data;
@@ -334,11 +362,13 @@ static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id)

static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev)
{
	struct hclge_vf_to_pf_msg send_msg;
	u8 resp_msg[2];
	int ret;

	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MEDIA_TYPE, 0, NULL, 0,
				   true, resp_msg, sizeof(resp_msg));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MEDIA_TYPE, 0);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg,
				   sizeof(resp_msg));
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"VF request to get the pf port media type failed %d",
@@ -425,11 +455,11 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)

static void hclgevf_request_link_info(struct hclgevf_dev *hdev)
{
	struct hclge_vf_to_pf_msg send_msg;
	int status;
	u8 resp_msg;

	status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_STATUS, 0, NULL,
				      0, false, &resp_msg, sizeof(resp_msg));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_STATUS, 0);
	status = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
	if (status)
		dev_err(&hdev->pdev->dev,
			"VF failed to fetch link status(%d) from PF", status);
@@ -465,17 +495,14 @@ static void hclgevf_update_link_mode(struct hclgevf_dev *hdev)
{
#define HCLGEVF_ADVERTISING	0
#define HCLGEVF_SUPPORTED	1
	u8 send_msg;
	u8 resp_msg;

	send_msg = HCLGEVF_ADVERTISING;
	hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0,
			     &send_msg, sizeof(send_msg), false,
			     &resp_msg, sizeof(resp_msg));
	send_msg = HCLGEVF_SUPPORTED;
	hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0,
			     &send_msg, sizeof(send_msg), false,
			     &resp_msg, sizeof(resp_msg));
	struct hclge_vf_to_pf_msg send_msg;

	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_MODE, 0);
	send_msg.data[0] = HCLGEVF_ADVERTISING;
	hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
	send_msg.data[0] = HCLGEVF_SUPPORTED;
	hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
@@ -677,19 +704,19 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size)
static int hclgevf_get_rss_hash_key(struct hclgevf_dev *hdev)
{
#define HCLGEVF_RSS_MBX_RESP_LEN	8

	struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
	u8 resp_msg[HCLGEVF_RSS_MBX_RESP_LEN];
	struct hclge_vf_to_pf_msg send_msg;
	u16 msg_num, hash_key_index;
	u8 index;
	int ret;

	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_RSS_KEY, 0);
	msg_num = (HCLGEVF_RSS_KEY_SIZE + HCLGEVF_RSS_MBX_RESP_LEN - 1) /
			HCLGEVF_RSS_MBX_RESP_LEN;
	for (index = 0; index < msg_num; index++) {
		ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_RSS_KEY, 0,
					   &index, sizeof(index),
					   true, resp_msg,
		send_msg.data[0] = index;
		ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg,
					   HCLGEVF_RSS_MBX_RESP_LEN);
		if (ret) {
			dev_err(&hdev->pdev->dev,
@@ -1001,44 +1028,32 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
				       struct hnae3_ring_chain_node *ring_chain)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;
	struct hnae3_ring_chain_node *node;
	struct hclge_mbx_vf_to_pf_cmd *req;
	struct hclgevf_desc desc;
	int i = 0;
	int status;
	u8 type;
	int i = 0;

	req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
	type = en ? HCLGE_MBX_MAP_RING_TO_VECTOR :
	memset(&send_msg, 0, sizeof(send_msg));
	send_msg.code = en ? HCLGE_MBX_MAP_RING_TO_VECTOR :
		HCLGE_MBX_UNMAP_RING_TO_VECTOR;
	send_msg.vector_id = vector_id;

	for (node = ring_chain; node; node = node->next) {
		int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM +
					HCLGE_MBX_RING_NODE_VARIABLE_NUM * i;

		if (i == 0) {
			hclgevf_cmd_setup_basic_desc(&desc,
						     HCLGEVF_OPC_MBX_VF_TO_PF,
						     false);
			req->msg[0] = type;
			req->msg[1] = vector_id;
		}

		req->msg[idx_offset] =
		send_msg.param[i].ring_type =
				hnae3_get_bit(node->flag, HNAE3_RING_TYPE_B);
		req->msg[idx_offset + 1] = node->tqp_index;
		req->msg[idx_offset + 2] = hnae3_get_field(node->int_gl_idx,

		send_msg.param[i].tqp_index = node->tqp_index;
		send_msg.param[i].int_gl_index =
					hnae3_get_field(node->int_gl_idx,
							HNAE3_RING_GL_IDX_M,
							HNAE3_RING_GL_IDX_S);

		i++;
		if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM -
		     HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
		     HCLGE_MBX_RING_NODE_VARIABLE_NUM) ||
		    !node->next) {
			req->msg[2] = i;
		if (i == HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM || !node->next) {
			send_msg.ring_num = i;

			status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
			status = hclgevf_send_mbx_msg(hdev, &send_msg, false,
						      NULL, 0);
			if (status) {
				dev_err(&hdev->pdev->dev,
					"Map TQP fail, status is %d.\n",
@@ -1046,11 +1061,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
				return status;
			}
			i = 0;
			hclgevf_cmd_setup_basic_desc(&desc,
						     HCLGEVF_OPC_MBX_VF_TO_PF,
						     false);
			req->msg[0] = type;
			req->msg[1] = vector_id;
		}
	}

@@ -1123,18 +1133,17 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
					bool en_uc_pmc, bool en_mc_pmc,
					bool en_bc_pmc)
{
	struct hclge_mbx_vf_to_pf_cmd *req;
	struct hclgevf_desc desc;
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
	hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
	req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE;
	req->msg[1] = en_bc_pmc ? 1 : 0;
	req->msg[2] = en_uc_pmc ? 1 : 0;
	req->msg[3] = en_mc_pmc ? 1 : 0;
	memset(&send_msg, 0, sizeof(send_msg));
	send_msg.code = HCLGE_MBX_SET_PROMISC_MODE;
	send_msg.en_bc = en_bc_pmc ? 1 : 0;
	send_msg.en_uc = en_uc_pmc ? 1 : 0;
	send_msg.en_mc = en_mc_pmc ? 1 : 0;

	ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);

	ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		dev_err(&hdev->pdev->dev,
			"Set promisc mode fail, status is %d.\n", ret);
@@ -1193,11 +1202,13 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle)

static int hclgevf_get_host_mac_addr(struct hclgevf_dev *hdev, u8 *p)
{
	struct hclge_vf_to_pf_msg send_msg;
	u8 host_mac[ETH_ALEN];
	int status;

	status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MAC_ADDR, 0, NULL, 0,
				      true, host_mac, ETH_ALEN);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MAC_ADDR, 0);
	status = hclgevf_send_mbx_msg(hdev, &send_msg, true, host_mac,
				      ETH_ALEN);
	if (status) {
		dev_err(&hdev->pdev->dev,
			"fail to get VF MAC from host %d", status);
@@ -1229,20 +1240,16 @@ static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr;
	struct hclge_vf_to_pf_msg send_msg;
	u8 *new_mac_addr = (u8 *)p;
	u8 msg_data[ETH_ALEN * 2];
	u16 subcode;
	int status;

	ether_addr_copy(msg_data, new_mac_addr);
	ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr);

	subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD :
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST, 0);
	send_msg.subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD :
			HCLGE_MBX_MAC_VLAN_UC_MODIFY;

	status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST,
				      subcode, msg_data, sizeof(msg_data),
				      true, NULL, 0);
	ether_addr_copy(send_msg.data, new_mac_addr);
	ether_addr_copy(&send_msg.data[ETH_ALEN], old_mac_addr);
	status = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
	if (!status)
		ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr);

@@ -1253,49 +1260,60 @@ static int hclgevf_add_uc_addr(struct hnae3_handle *handle,
			       const unsigned char *addr)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST,
				    HCLGE_MBX_MAC_VLAN_UC_ADD,
				    addr, ETH_ALEN, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST,
			       HCLGE_MBX_MAC_VLAN_UC_ADD);
	ether_addr_copy(send_msg.data, addr);
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_rm_uc_addr(struct hnae3_handle *handle,
			      const unsigned char *addr)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST,
				    HCLGE_MBX_MAC_VLAN_UC_REMOVE,
				    addr, ETH_ALEN, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST,
			       HCLGE_MBX_MAC_VLAN_UC_REMOVE);
	ether_addr_copy(send_msg.data, addr);
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_add_mc_addr(struct hnae3_handle *handle,
			       const unsigned char *addr)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST,
				    HCLGE_MBX_MAC_VLAN_MC_ADD,
				    addr, ETH_ALEN, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MULTICAST,
			       HCLGE_MBX_MAC_VLAN_MC_ADD);
	ether_addr_copy(send_msg.data, addr);
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_rm_mc_addr(struct hnae3_handle *handle,
			      const unsigned char *addr)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST,
				    HCLGE_MBX_MAC_VLAN_MC_REMOVE,
				    addr, ETH_ALEN, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MULTICAST,
			       HCLGE_MBX_MAC_VLAN_MC_REMOVE);
	ether_addr_copy(send_msg.data, addr);
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
				   __be16 proto, u16 vlan_id,
				   bool is_kill)
{
#define HCLGEVF_VLAN_MBX_MSG_LEN 5
#define HCLGEVF_VLAN_MBX_IS_KILL_OFFSET	0
#define HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET	1
#define HCLGEVF_VLAN_MBX_PROTO_OFFSET	3

	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 msg_data[HCLGEVF_VLAN_MBX_MSG_LEN];
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	if (vlan_id > HCLGEVF_MAX_VLAN_ID)
@@ -1313,16 +1331,18 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
		return -EBUSY;
	}

	msg_data[0] = is_kill;
	memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id));
	memcpy(&msg_data[3], &proto, sizeof(proto));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
			       HCLGE_MBX_VLAN_FILTER);
	send_msg.data[HCLGEVF_VLAN_MBX_IS_KILL_OFFSET] = is_kill;
	memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET], &vlan_id,
	       sizeof(vlan_id));
	memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_PROTO_OFFSET], &proto,
	       sizeof(proto));
	/* when remove hw vlan filter failed, record the vlan id,
	 * and try to remove it from hw later, to be consistence
	 * with stack.
	 */
	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
				   HCLGE_MBX_VLAN_FILTER, msg_data,
				   HCLGEVF_VLAN_MBX_MSG_LEN, true, NULL, 0);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
	if (is_kill && ret)
		set_bit(vlan_id, hdev->vlan_del_fail_bmap);

@@ -1355,37 +1375,38 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev)
static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 msg_data;
	struct hclge_vf_to_pf_msg send_msg;

	msg_data = enable ? 1 : 0;
	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
				    HCLGE_MBX_VLAN_RX_OFF_CFG, &msg_data,
				    1, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
			       HCLGE_MBX_VLAN_RX_OFF_CFG);
	send_msg.data[0] = enable ? 1 : 0;
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 msg_data[2];
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	memcpy(msg_data, &queue_id, sizeof(queue_id));

	/* disable vf queue before send queue reset msg to PF */
	ret = hclgevf_tqp_enable(hdev, queue_id, 0, false);
	if (ret)
		return ret;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
				    sizeof(msg_data), true, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_QUEUE_RESET, 0);
	memcpy(send_msg.data, &queue_id, sizeof(queue_id));
	return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
}

static int hclgevf_set_mtu(struct hnae3_handle *handle, int new_mtu)
{
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	struct hclge_vf_to_pf_msg send_msg;

	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MTU, 0, (u8 *)&new_mtu,
				    sizeof(new_mtu), true, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MTU, 0);
	memcpy(send_msg.data, &new_mtu, sizeof(new_mtu));
	return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
}

static int hclgevf_notify_client(struct hclgevf_dev *hdev,
@@ -1500,11 +1521,12 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
{
#define HCLGEVF_RESET_SYNC_TIME 100

	struct hclge_vf_to_pf_msg send_msg;
	int ret = 0;

	if (hdev->reset_type == HNAE3_VF_FUNC_RESET) {
		ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL,
					   0, true, NULL, sizeof(u8));
		hclgevf_build_send_msg(&send_msg, HCLGE_MBX_RESET, 0);
		ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
		hdev->rst_stats.vf_func_rst_cnt++;
	}

@@ -1881,14 +1903,14 @@ static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev)

static void hclgevf_keep_alive(struct hclgevf_dev *hdev)
{
	u8 respmsg;
	struct hclge_vf_to_pf_msg send_msg;
	int ret;

	if (test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state))
		return;

	ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_KEEP_ALIVE, 0, NULL,
				   0, false, &respmsg, sizeof(respmsg));
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_KEEP_ALIVE, 0);
	ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
	if (ret)
		dev_err(&hdev->pdev->dev,
			"VF sends keep alive cmd failed(=%d)\n", ret);
@@ -2245,12 +2267,16 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle)

static int hclgevf_set_alive(struct hnae3_handle *handle, bool alive)
{
#define HCLGEVF_STATE_ALIVE	1
#define HCLGEVF_STATE_NOT_ALIVE	0

	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
	u8 msg_data;
	struct hclge_vf_to_pf_msg send_msg;

	msg_data = alive ? 1 : 0;
	return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_ALIVE,
				    0, &msg_data, 1, false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_ALIVE, 0);
	send_msg.data[0] = alive ? HCLGEVF_STATE_ALIVE :
				HCLGEVF_STATE_NOT_ALIVE;
	return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
}

static int hclgevf_client_start(struct hnae3_handle *handle)
@@ -2804,10 +2830,12 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)

static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
{
	struct hclge_vf_to_pf_msg send_msg;

	hclgevf_state_uninit(hdev);

	hclgevf_send_mbx_msg(hdev, HCLGE_MBX_VF_UNINIT, 0, NULL, 0,
			     false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_VF_UNINIT, 0);
	hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);

	if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
		hclgevf_misc_irq_uninit(hdev);
@@ -3104,16 +3132,17 @@ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
					u8 *port_base_vlan_info, u8 data_size)
{
	struct hnae3_handle *nic = &hdev->nic;
	struct hclge_vf_to_pf_msg send_msg;

	rtnl_lock();
	hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
	rtnl_unlock();

	/* send msg to PF and wait update port based vlan info */
	hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
			     HCLGE_MBX_PORT_BASE_VLAN_CFG,
			     port_base_vlan_info, data_size,
			     false, NULL, 0);
	hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
			       HCLGE_MBX_PORT_BASE_VLAN_CFG);
	memcpy(send_msg.data, port_base_vlan_info, data_size);
	hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);

	if (state == HNAE3_PORT_BASE_VLAN_DISABLE)
		nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE;
+2 −2
Original line number Diff line number Diff line
@@ -305,8 +305,8 @@ static inline bool hclgevf_is_reset_pending(struct hclgevf_dev *hdev)
	return !!hdev->reset_pending;
}

int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
			 const u8 *msg_data, u8 msg_len, bool need_resp,
int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
			 struct hclge_vf_to_pf_msg *send_msg, bool need_resp,
			 u8 *resp_data, u16 resp_len);
void hclgevf_mbx_handler(struct hclgevf_dev *hdev);
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev);
+27 −23
Original line number Diff line number Diff line
@@ -5,6 +5,11 @@
#include "hclgevf_main.h"
#include "hnae3.h"

static int hclgevf_resp_to_errno(u16 resp_code)
{
	return resp_code ? -resp_code : 0;
}

static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev)
{
	/* this function should be called with mbx_resp.mbx_mutex held
@@ -79,8 +84,8 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1,
	return 0;
}

int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
			 const u8 *msg_data, u8 msg_len, bool need_resp,
int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
			 struct hclge_vf_to_pf_msg *send_msg, bool need_resp,
			 u8 *resp_data, u16 resp_len)
{
	struct hclge_mbx_vf_to_pf_cmd *req;
@@ -89,21 +94,17 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,

	req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;

	/* first two bytes are reserved for code & subcode */
	if (msg_len > (HCLGE_MBX_MAX_MSG_SIZE - 2)) {
	if (!send_msg) {
		dev_err(&hdev->pdev->dev,
			"VF send mbx msg fail, msg len %d exceeds max len %d\n",
			msg_len, HCLGE_MBX_MAX_MSG_SIZE);
			"failed to send mbx, msg is NULL\n");
		return -EINVAL;
	}

	hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
	req->mbx_need_resp |= need_resp ? HCLGE_MBX_NEED_RESP_BIT :
					  ~HCLGE_MBX_NEED_RESP_BIT;
	req->msg[0] = code;
	req->msg[1] = subcode;
	if (msg_data)
		memcpy(&req->msg[2], msg_data, msg_len);
	if (need_resp)
		hnae3_set_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B, 1);

	memcpy(&req->msg, send_msg, sizeof(struct hclge_vf_to_pf_msg));

	/* synchronous send */
	if (need_resp) {
@@ -118,7 +119,8 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
			return status;
		}

		status = hclgevf_get_mbx_resp(hdev, code, subcode, resp_data,
		status = hclgevf_get_mbx_resp(hdev, send_msg->code,
					      send_msg->subcode, resp_data,
					      resp_len);
		mutex_unlock(&hdev->mbx_resp.mbx_mutex);
	} else {
@@ -169,7 +171,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
		if (unlikely(!hnae3_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) {
			dev_warn(&hdev->pdev->dev,
				 "dropped invalid mailbox message, code = %u\n",
				 req->msg[0]);
				 req->msg.code);

			/* dropping/not processing this invalid message */
			crq->desc[crq->next_to_use].flag = 0;
@@ -183,19 +185,21 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
		 * timeout and simultaneously queue the async messages for later
		 * prcessing in context of mailbox task i.e. the slow path.
		 */
		switch (req->msg[0]) {
		switch (req->msg.code) {
		case HCLGE_MBX_PF_VF_RESP:
			if (resp->received_resp)
				dev_warn(&hdev->pdev->dev,
					 "VF mbx resp flag not clear(%u)\n",
					 req->msg[1]);
					 req->msg.vf_mbx_msg_code);
			resp->received_resp = true;

			resp->origin_mbx_msg = (req->msg[1] << 16);
			resp->origin_mbx_msg |= req->msg[2];
			resp->resp_status = req->msg[3];
			resp->origin_mbx_msg =
					(req->msg.vf_mbx_msg_code << 16);
			resp->origin_mbx_msg |= req->msg.vf_mbx_msg_subcode;
			resp->resp_status =
				hclgevf_resp_to_errno(req->msg.resp_status);

			temp = (u8 *)&req->msg[4];
			temp = (u8 *)req->msg.resp_data;
			for (i = 0; i < HCLGE_MBX_MAX_RESP_DATA_SIZE; i++) {
				resp->additional_info[i] = *temp;
				temp++;
@@ -220,13 +224,13 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
			    HCLGE_MBX_MAX_ARQ_MSG_NUM) {
				dev_warn(&hdev->pdev->dev,
					 "Async Q full, dropping msg(%u)\n",
					 req->msg[1]);
					 req->msg.code);
				break;
			}

			/* tail the async message in arq */
			msg_q = hdev->arq.msg_q[hdev->arq.tail];
			memcpy(&msg_q[0], req->msg,
			memcpy(&msg_q[0], &req->msg,
			       HCLGE_MBX_MAX_ARQ_MSG_SIZE * sizeof(u16));
			hclge_mbx_tail_ptr_move_arq(hdev->arq);
			atomic_inc(&hdev->arq.count);
@@ -237,7 +241,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
		default:
			dev_err(&hdev->pdev->dev,
				"VF received unsupported(%u) mbx msg from PF\n",
				req->msg[0]);
				req->msg.code);
			break;
		}
		crq->desc[crq->next_to_use].flag = 0;