162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright(c) 2013 - 2018 Intel Corporation. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "iavf.h"
562306a36Sopenharmony_ci#include "iavf_prototype.h"
662306a36Sopenharmony_ci#include "iavf_client.h"
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/**
962306a36Sopenharmony_ci * iavf_send_pf_msg
1062306a36Sopenharmony_ci * @adapter: adapter structure
1162306a36Sopenharmony_ci * @op: virtual channel opcode
1262306a36Sopenharmony_ci * @msg: pointer to message buffer
1362306a36Sopenharmony_ci * @len: message length
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * Send message to PF and print status if failure.
1662306a36Sopenharmony_ci **/
1762306a36Sopenharmony_cistatic int iavf_send_pf_msg(struct iavf_adapter *adapter,
1862306a36Sopenharmony_ci			    enum virtchnl_ops op, u8 *msg, u16 len)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	struct iavf_hw *hw = &adapter->hw;
2162306a36Sopenharmony_ci	enum iavf_status status;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
2462306a36Sopenharmony_ci		return 0; /* nothing to see here, move along */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	status = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
2762306a36Sopenharmony_ci	if (status)
2862306a36Sopenharmony_ci		dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, status %s, aq_err %s\n",
2962306a36Sopenharmony_ci			op, iavf_stat_str(hw, status),
3062306a36Sopenharmony_ci			iavf_aq_str(hw, hw->aq.asq_last_status));
3162306a36Sopenharmony_ci	return iavf_status_to_errno(status);
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/**
3562306a36Sopenharmony_ci * iavf_send_api_ver
3662306a36Sopenharmony_ci * @adapter: adapter structure
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * Send API version admin queue message to the PF. The reply is not checked
3962306a36Sopenharmony_ci * in this function. Returns 0 if the message was successfully
4062306a36Sopenharmony_ci * sent, or one of the IAVF_ADMIN_QUEUE_ERROR_ statuses if not.
4162306a36Sopenharmony_ci **/
4262306a36Sopenharmony_ciint iavf_send_api_ver(struct iavf_adapter *adapter)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	struct virtchnl_version_info vvi;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	vvi.major = VIRTCHNL_VERSION_MAJOR;
4762306a36Sopenharmony_ci	vvi.minor = VIRTCHNL_VERSION_MINOR;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	return iavf_send_pf_msg(adapter, VIRTCHNL_OP_VERSION, (u8 *)&vvi,
5062306a36Sopenharmony_ci				sizeof(vvi));
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * iavf_poll_virtchnl_msg
5562306a36Sopenharmony_ci * @hw: HW configuration structure
5662306a36Sopenharmony_ci * @event: event to populate on success
5762306a36Sopenharmony_ci * @op_to_poll: requested virtchnl op to poll for
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * Initialize poll for virtchnl msg matching the requested_op. Returns 0
6062306a36Sopenharmony_ci * if a message of the correct opcode is in the queue or an error code
6162306a36Sopenharmony_ci * if no message matching the op code is waiting and other failures.
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_cistatic int
6462306a36Sopenharmony_ciiavf_poll_virtchnl_msg(struct iavf_hw *hw, struct iavf_arq_event_info *event,
6562306a36Sopenharmony_ci		       enum virtchnl_ops op_to_poll)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	enum virtchnl_ops received_op;
6862306a36Sopenharmony_ci	enum iavf_status status;
6962306a36Sopenharmony_ci	u32 v_retval;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	while (1) {
7262306a36Sopenharmony_ci		/* When the AQ is empty, iavf_clean_arq_element will return
7362306a36Sopenharmony_ci		 * nonzero and this loop will terminate.
7462306a36Sopenharmony_ci		 */
7562306a36Sopenharmony_ci		status = iavf_clean_arq_element(hw, event, NULL);
7662306a36Sopenharmony_ci		if (status != IAVF_SUCCESS)
7762306a36Sopenharmony_ci			return iavf_status_to_errno(status);
7862306a36Sopenharmony_ci		received_op =
7962306a36Sopenharmony_ci		    (enum virtchnl_ops)le32_to_cpu(event->desc.cookie_high);
8062306a36Sopenharmony_ci		if (op_to_poll == received_op)
8162306a36Sopenharmony_ci			break;
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	v_retval = le32_to_cpu(event->desc.cookie_low);
8562306a36Sopenharmony_ci	return virtchnl_status_to_errno((enum virtchnl_status_code)v_retval);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/**
8962306a36Sopenharmony_ci * iavf_verify_api_ver
9062306a36Sopenharmony_ci * @adapter: adapter structure
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci * Compare API versions with the PF. Must be called after admin queue is
9362306a36Sopenharmony_ci * initialized. Returns 0 if API versions match, -EIO if they do not,
9462306a36Sopenharmony_ci * IAVF_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty, and any errors
9562306a36Sopenharmony_ci * from the firmware are propagated.
9662306a36Sopenharmony_ci **/
9762306a36Sopenharmony_ciint iavf_verify_api_ver(struct iavf_adapter *adapter)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	struct iavf_arq_event_info event;
10062306a36Sopenharmony_ci	int err;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
10362306a36Sopenharmony_ci	event.msg_buf = kzalloc(IAVF_MAX_AQ_BUF_SIZE, GFP_KERNEL);
10462306a36Sopenharmony_ci	if (!event.msg_buf)
10562306a36Sopenharmony_ci		return -ENOMEM;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	err = iavf_poll_virtchnl_msg(&adapter->hw, &event, VIRTCHNL_OP_VERSION);
10862306a36Sopenharmony_ci	if (!err) {
10962306a36Sopenharmony_ci		struct virtchnl_version_info *pf_vvi =
11062306a36Sopenharmony_ci			(struct virtchnl_version_info *)event.msg_buf;
11162306a36Sopenharmony_ci		adapter->pf_version = *pf_vvi;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci		if (pf_vvi->major > VIRTCHNL_VERSION_MAJOR ||
11462306a36Sopenharmony_ci		    (pf_vvi->major == VIRTCHNL_VERSION_MAJOR &&
11562306a36Sopenharmony_ci		     pf_vvi->minor > VIRTCHNL_VERSION_MINOR))
11662306a36Sopenharmony_ci			err = -EIO;
11762306a36Sopenharmony_ci	}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	kfree(event.msg_buf);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	return err;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/**
12562306a36Sopenharmony_ci * iavf_send_vf_config_msg
12662306a36Sopenharmony_ci * @adapter: adapter structure
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * Send VF configuration request admin queue message to the PF. The reply
12962306a36Sopenharmony_ci * is not checked in this function. Returns 0 if the message was
13062306a36Sopenharmony_ci * successfully sent, or one of the IAVF_ADMIN_QUEUE_ERROR_ statuses if not.
13162306a36Sopenharmony_ci **/
13262306a36Sopenharmony_ciint iavf_send_vf_config_msg(struct iavf_adapter *adapter)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	u32 caps;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	caps = VIRTCHNL_VF_OFFLOAD_L2 |
13762306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_RSS_PF |
13862306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_RSS_AQ |
13962306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_RSS_REG |
14062306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_VLAN |
14162306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_WB_ON_ITR |
14262306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 |
14362306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_ENCAP |
14462306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
14562306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
14662306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
14762306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_ADQ |
14862306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_USO |
14962306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_FDIR_PF |
15062306a36Sopenharmony_ci	       VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
15162306a36Sopenharmony_ci	       VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES;
15462306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_GET_CONFIG;
15562306a36Sopenharmony_ci	if (PF_IS_V11(adapter))
15662306a36Sopenharmony_ci		return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_VF_RESOURCES,
15762306a36Sopenharmony_ci					(u8 *)&caps, sizeof(caps));
15862306a36Sopenharmony_ci	else
15962306a36Sopenharmony_ci		return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_VF_RESOURCES,
16062306a36Sopenharmony_ci					NULL, 0);
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ciint iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS;
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	if (!VLAN_V2_ALLOWED(adapter))
16862306a36Sopenharmony_ci		return -EOPNOTSUPP;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS,
17362306a36Sopenharmony_ci				NULL, 0);
17462306a36Sopenharmony_ci}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci/**
17762306a36Sopenharmony_ci * iavf_validate_num_queues
17862306a36Sopenharmony_ci * @adapter: adapter structure
17962306a36Sopenharmony_ci *
18062306a36Sopenharmony_ci * Validate that the number of queues the PF has sent in
18162306a36Sopenharmony_ci * VIRTCHNL_OP_GET_VF_RESOURCES is not larger than the VF can handle.
18262306a36Sopenharmony_ci **/
18362306a36Sopenharmony_cistatic void iavf_validate_num_queues(struct iavf_adapter *adapter)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	if (adapter->vf_res->num_queue_pairs > IAVF_MAX_REQ_QUEUES) {
18662306a36Sopenharmony_ci		struct virtchnl_vsi_resource *vsi_res;
18762306a36Sopenharmony_ci		int i;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "Received %d queues, but can only have a max of %d\n",
19062306a36Sopenharmony_ci			 adapter->vf_res->num_queue_pairs,
19162306a36Sopenharmony_ci			 IAVF_MAX_REQ_QUEUES);
19262306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "Fixing by reducing queues to %d\n",
19362306a36Sopenharmony_ci			 IAVF_MAX_REQ_QUEUES);
19462306a36Sopenharmony_ci		adapter->vf_res->num_queue_pairs = IAVF_MAX_REQ_QUEUES;
19562306a36Sopenharmony_ci		for (i = 0; i < adapter->vf_res->num_vsis; i++) {
19662306a36Sopenharmony_ci			vsi_res = &adapter->vf_res->vsi_res[i];
19762306a36Sopenharmony_ci			vsi_res->num_queue_pairs = IAVF_MAX_REQ_QUEUES;
19862306a36Sopenharmony_ci		}
19962306a36Sopenharmony_ci	}
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/**
20362306a36Sopenharmony_ci * iavf_get_vf_config
20462306a36Sopenharmony_ci * @adapter: private adapter structure
20562306a36Sopenharmony_ci *
20662306a36Sopenharmony_ci * Get VF configuration from PF and populate hw structure. Must be called after
20762306a36Sopenharmony_ci * admin queue is initialized. Busy waits until response is received from PF,
20862306a36Sopenharmony_ci * with maximum timeout. Response from PF is returned in the buffer for further
20962306a36Sopenharmony_ci * processing by the caller.
21062306a36Sopenharmony_ci **/
21162306a36Sopenharmony_ciint iavf_get_vf_config(struct iavf_adapter *adapter)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	struct iavf_hw *hw = &adapter->hw;
21462306a36Sopenharmony_ci	struct iavf_arq_event_info event;
21562306a36Sopenharmony_ci	u16 len;
21662306a36Sopenharmony_ci	int err;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	len = IAVF_VIRTCHNL_VF_RESOURCE_SIZE;
21962306a36Sopenharmony_ci	event.buf_len = len;
22062306a36Sopenharmony_ci	event.msg_buf = kzalloc(len, GFP_KERNEL);
22162306a36Sopenharmony_ci	if (!event.msg_buf)
22262306a36Sopenharmony_ci		return -ENOMEM;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	err = iavf_poll_virtchnl_msg(hw, &event, VIRTCHNL_OP_GET_VF_RESOURCES);
22562306a36Sopenharmony_ci	memcpy(adapter->vf_res, event.msg_buf, min(event.msg_len, len));
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	/* some PFs send more queues than we should have so validate that
22862306a36Sopenharmony_ci	 * we aren't getting too many queues
22962306a36Sopenharmony_ci	 */
23062306a36Sopenharmony_ci	if (!err)
23162306a36Sopenharmony_ci		iavf_validate_num_queues(adapter);
23262306a36Sopenharmony_ci	iavf_vf_parse_hw_config(hw, adapter->vf_res);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	kfree(event.msg_buf);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	return err;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ciint iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
24062306a36Sopenharmony_ci{
24162306a36Sopenharmony_ci	struct iavf_arq_event_info event;
24262306a36Sopenharmony_ci	int err;
24362306a36Sopenharmony_ci	u16 len;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	len = sizeof(struct virtchnl_vlan_caps);
24662306a36Sopenharmony_ci	event.buf_len = len;
24762306a36Sopenharmony_ci	event.msg_buf = kzalloc(len, GFP_KERNEL);
24862306a36Sopenharmony_ci	if (!event.msg_buf)
24962306a36Sopenharmony_ci		return -ENOMEM;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	err = iavf_poll_virtchnl_msg(&adapter->hw, &event,
25262306a36Sopenharmony_ci				     VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS);
25362306a36Sopenharmony_ci	if (!err)
25462306a36Sopenharmony_ci		memcpy(&adapter->vlan_v2_caps, event.msg_buf,
25562306a36Sopenharmony_ci		       min(event.msg_len, len));
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	kfree(event.msg_buf);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	return err;
26062306a36Sopenharmony_ci}
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci/**
26362306a36Sopenharmony_ci * iavf_configure_queues
26462306a36Sopenharmony_ci * @adapter: adapter structure
26562306a36Sopenharmony_ci *
26662306a36Sopenharmony_ci * Request that the PF set up our (previously allocated) queues.
26762306a36Sopenharmony_ci **/
26862306a36Sopenharmony_civoid iavf_configure_queues(struct iavf_adapter *adapter)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	struct virtchnl_vsi_queue_config_info *vqci;
27162306a36Sopenharmony_ci	int i, max_frame = adapter->vf_res->max_mtu;
27262306a36Sopenharmony_ci	int pairs = adapter->num_active_queues;
27362306a36Sopenharmony_ci	struct virtchnl_queue_pair_info *vqpi;
27462306a36Sopenharmony_ci	size_t len;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
27762306a36Sopenharmony_ci		max_frame = IAVF_MAX_RXBUFFER;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
28062306a36Sopenharmony_ci		/* bail because we already have a command pending */
28162306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
28262306a36Sopenharmony_ci			adapter->current_op);
28362306a36Sopenharmony_ci		return;
28462306a36Sopenharmony_ci	}
28562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
28662306a36Sopenharmony_ci	len = virtchnl_struct_size(vqci, qpair, pairs);
28762306a36Sopenharmony_ci	vqci = kzalloc(len, GFP_KERNEL);
28862306a36Sopenharmony_ci	if (!vqci)
28962306a36Sopenharmony_ci		return;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* Limit maximum frame size when jumbo frames is not enabled */
29262306a36Sopenharmony_ci	if (!(adapter->flags & IAVF_FLAG_LEGACY_RX) &&
29362306a36Sopenharmony_ci	    (adapter->netdev->mtu <= ETH_DATA_LEN))
29462306a36Sopenharmony_ci		max_frame = IAVF_RXBUFFER_1536 - NET_IP_ALIGN;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	vqci->vsi_id = adapter->vsi_res->vsi_id;
29762306a36Sopenharmony_ci	vqci->num_queue_pairs = pairs;
29862306a36Sopenharmony_ci	vqpi = vqci->qpair;
29962306a36Sopenharmony_ci	/* Size check is not needed here - HW max is 16 queue pairs, and we
30062306a36Sopenharmony_ci	 * can fit info for 31 of them into the AQ buffer before it overflows.
30162306a36Sopenharmony_ci	 */
30262306a36Sopenharmony_ci	for (i = 0; i < pairs; i++) {
30362306a36Sopenharmony_ci		vqpi->txq.vsi_id = vqci->vsi_id;
30462306a36Sopenharmony_ci		vqpi->txq.queue_id = i;
30562306a36Sopenharmony_ci		vqpi->txq.ring_len = adapter->tx_rings[i].count;
30662306a36Sopenharmony_ci		vqpi->txq.dma_ring_addr = adapter->tx_rings[i].dma;
30762306a36Sopenharmony_ci		vqpi->rxq.vsi_id = vqci->vsi_id;
30862306a36Sopenharmony_ci		vqpi->rxq.queue_id = i;
30962306a36Sopenharmony_ci		vqpi->rxq.ring_len = adapter->rx_rings[i].count;
31062306a36Sopenharmony_ci		vqpi->rxq.dma_ring_addr = adapter->rx_rings[i].dma;
31162306a36Sopenharmony_ci		vqpi->rxq.max_pkt_size = max_frame;
31262306a36Sopenharmony_ci		vqpi->rxq.databuffer_size =
31362306a36Sopenharmony_ci			ALIGN(adapter->rx_rings[i].rx_buf_len,
31462306a36Sopenharmony_ci			      BIT_ULL(IAVF_RXQ_CTX_DBUFF_SHIFT));
31562306a36Sopenharmony_ci		vqpi++;
31662306a36Sopenharmony_ci	}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_QUEUES;
31962306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
32062306a36Sopenharmony_ci			 (u8 *)vqci, len);
32162306a36Sopenharmony_ci	kfree(vqci);
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci/**
32562306a36Sopenharmony_ci * iavf_enable_queues
32662306a36Sopenharmony_ci * @adapter: adapter structure
32762306a36Sopenharmony_ci *
32862306a36Sopenharmony_ci * Request that the PF enable all of our queues.
32962306a36Sopenharmony_ci **/
33062306a36Sopenharmony_civoid iavf_enable_queues(struct iavf_adapter *adapter)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	struct virtchnl_queue_select vqs;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
33562306a36Sopenharmony_ci		/* bail because we already have a command pending */
33662306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot enable queues, command %d pending\n",
33762306a36Sopenharmony_ci			adapter->current_op);
33862306a36Sopenharmony_ci		return;
33962306a36Sopenharmony_ci	}
34062306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ENABLE_QUEUES;
34162306a36Sopenharmony_ci	vqs.vsi_id = adapter->vsi_res->vsi_id;
34262306a36Sopenharmony_ci	vqs.tx_queues = BIT(adapter->num_active_queues) - 1;
34362306a36Sopenharmony_ci	vqs.rx_queues = vqs.tx_queues;
34462306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_QUEUES;
34562306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_QUEUES,
34662306a36Sopenharmony_ci			 (u8 *)&vqs, sizeof(vqs));
34762306a36Sopenharmony_ci}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci/**
35062306a36Sopenharmony_ci * iavf_disable_queues
35162306a36Sopenharmony_ci * @adapter: adapter structure
35262306a36Sopenharmony_ci *
35362306a36Sopenharmony_ci * Request that the PF disable all of our queues.
35462306a36Sopenharmony_ci **/
35562306a36Sopenharmony_civoid iavf_disable_queues(struct iavf_adapter *adapter)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	struct virtchnl_queue_select vqs;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
36062306a36Sopenharmony_ci		/* bail because we already have a command pending */
36162306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot disable queues, command %d pending\n",
36262306a36Sopenharmony_ci			adapter->current_op);
36362306a36Sopenharmony_ci		return;
36462306a36Sopenharmony_ci	}
36562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DISABLE_QUEUES;
36662306a36Sopenharmony_ci	vqs.vsi_id = adapter->vsi_res->vsi_id;
36762306a36Sopenharmony_ci	vqs.tx_queues = BIT(adapter->num_active_queues) - 1;
36862306a36Sopenharmony_ci	vqs.rx_queues = vqs.tx_queues;
36962306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_QUEUES;
37062306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_QUEUES,
37162306a36Sopenharmony_ci			 (u8 *)&vqs, sizeof(vqs));
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci/**
37562306a36Sopenharmony_ci * iavf_map_queues
37662306a36Sopenharmony_ci * @adapter: adapter structure
37762306a36Sopenharmony_ci *
37862306a36Sopenharmony_ci * Request that the PF map queues to interrupt vectors. Misc causes, including
37962306a36Sopenharmony_ci * admin queue, are always mapped to vector 0.
38062306a36Sopenharmony_ci **/
38162306a36Sopenharmony_civoid iavf_map_queues(struct iavf_adapter *adapter)
38262306a36Sopenharmony_ci{
38362306a36Sopenharmony_ci	struct virtchnl_irq_map_info *vimi;
38462306a36Sopenharmony_ci	struct virtchnl_vector_map *vecmap;
38562306a36Sopenharmony_ci	struct iavf_q_vector *q_vector;
38662306a36Sopenharmony_ci	int v_idx, q_vectors;
38762306a36Sopenharmony_ci	size_t len;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
39062306a36Sopenharmony_ci		/* bail because we already have a command pending */
39162306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot map queues to vectors, command %d pending\n",
39262306a36Sopenharmony_ci			adapter->current_op);
39362306a36Sopenharmony_ci		return;
39462306a36Sopenharmony_ci	}
39562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_CONFIG_IRQ_MAP;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	q_vectors = adapter->num_msix_vectors - NONQ_VECS;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	len = virtchnl_struct_size(vimi, vecmap, adapter->num_msix_vectors);
40062306a36Sopenharmony_ci	vimi = kzalloc(len, GFP_KERNEL);
40162306a36Sopenharmony_ci	if (!vimi)
40262306a36Sopenharmony_ci		return;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	vimi->num_vectors = adapter->num_msix_vectors;
40562306a36Sopenharmony_ci	/* Queue vectors first */
40662306a36Sopenharmony_ci	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
40762306a36Sopenharmony_ci		q_vector = &adapter->q_vectors[v_idx];
40862306a36Sopenharmony_ci		vecmap = &vimi->vecmap[v_idx];
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci		vecmap->vsi_id = adapter->vsi_res->vsi_id;
41162306a36Sopenharmony_ci		vecmap->vector_id = v_idx + NONQ_VECS;
41262306a36Sopenharmony_ci		vecmap->txq_map = q_vector->ring_mask;
41362306a36Sopenharmony_ci		vecmap->rxq_map = q_vector->ring_mask;
41462306a36Sopenharmony_ci		vecmap->rxitr_idx = IAVF_RX_ITR;
41562306a36Sopenharmony_ci		vecmap->txitr_idx = IAVF_TX_ITR;
41662306a36Sopenharmony_ci	}
41762306a36Sopenharmony_ci	/* Misc vector last - this is only for AdminQ messages */
41862306a36Sopenharmony_ci	vecmap = &vimi->vecmap[v_idx];
41962306a36Sopenharmony_ci	vecmap->vsi_id = adapter->vsi_res->vsi_id;
42062306a36Sopenharmony_ci	vecmap->vector_id = 0;
42162306a36Sopenharmony_ci	vecmap->txq_map = 0;
42262306a36Sopenharmony_ci	vecmap->rxq_map = 0;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_MAP_VECTORS;
42562306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_IRQ_MAP,
42662306a36Sopenharmony_ci			 (u8 *)vimi, len);
42762306a36Sopenharmony_ci	kfree(vimi);
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/**
43162306a36Sopenharmony_ci * iavf_set_mac_addr_type - Set the correct request type from the filter type
43262306a36Sopenharmony_ci * @virtchnl_ether_addr: pointer to requested list element
43362306a36Sopenharmony_ci * @filter: pointer to requested filter
43462306a36Sopenharmony_ci **/
43562306a36Sopenharmony_cistatic void
43662306a36Sopenharmony_ciiavf_set_mac_addr_type(struct virtchnl_ether_addr *virtchnl_ether_addr,
43762306a36Sopenharmony_ci		       const struct iavf_mac_filter *filter)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	virtchnl_ether_addr->type = filter->is_primary ?
44062306a36Sopenharmony_ci		VIRTCHNL_ETHER_ADDR_PRIMARY :
44162306a36Sopenharmony_ci		VIRTCHNL_ETHER_ADDR_EXTRA;
44262306a36Sopenharmony_ci}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci/**
44562306a36Sopenharmony_ci * iavf_add_ether_addrs
44662306a36Sopenharmony_ci * @adapter: adapter structure
44762306a36Sopenharmony_ci *
44862306a36Sopenharmony_ci * Request that the PF add one or more addresses to our filters.
44962306a36Sopenharmony_ci **/
45062306a36Sopenharmony_civoid iavf_add_ether_addrs(struct iavf_adapter *adapter)
45162306a36Sopenharmony_ci{
45262306a36Sopenharmony_ci	struct virtchnl_ether_addr_list *veal;
45362306a36Sopenharmony_ci	struct iavf_mac_filter *f;
45462306a36Sopenharmony_ci	int i = 0, count = 0;
45562306a36Sopenharmony_ci	bool more = false;
45662306a36Sopenharmony_ci	size_t len;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
45962306a36Sopenharmony_ci		/* bail because we already have a command pending */
46062306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot add filters, command %d pending\n",
46162306a36Sopenharmony_ci			adapter->current_op);
46262306a36Sopenharmony_ci		return;
46362306a36Sopenharmony_ci	}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	list_for_each_entry(f, &adapter->mac_filter_list, list) {
46862306a36Sopenharmony_ci		if (f->add)
46962306a36Sopenharmony_ci			count++;
47062306a36Sopenharmony_ci	}
47162306a36Sopenharmony_ci	if (!count) {
47262306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
47362306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
47462306a36Sopenharmony_ci		return;
47562306a36Sopenharmony_ci	}
47662306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	len = virtchnl_struct_size(veal, list, count);
47962306a36Sopenharmony_ci	if (len > IAVF_MAX_AQ_BUF_SIZE) {
48062306a36Sopenharmony_ci		dev_warn(&adapter->pdev->dev, "Too many add MAC changes in one request\n");
48162306a36Sopenharmony_ci		while (len > IAVF_MAX_AQ_BUF_SIZE)
48262306a36Sopenharmony_ci			len = virtchnl_struct_size(veal, list, --count);
48362306a36Sopenharmony_ci		more = true;
48462306a36Sopenharmony_ci	}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	veal = kzalloc(len, GFP_ATOMIC);
48762306a36Sopenharmony_ci	if (!veal) {
48862306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
48962306a36Sopenharmony_ci		return;
49062306a36Sopenharmony_ci	}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	veal->vsi_id = adapter->vsi_res->vsi_id;
49362306a36Sopenharmony_ci	veal->num_elements = count;
49462306a36Sopenharmony_ci	list_for_each_entry(f, &adapter->mac_filter_list, list) {
49562306a36Sopenharmony_ci		if (f->add) {
49662306a36Sopenharmony_ci			ether_addr_copy(veal->list[i].addr, f->macaddr);
49762306a36Sopenharmony_ci			iavf_set_mac_addr_type(&veal->list[i], f);
49862306a36Sopenharmony_ci			i++;
49962306a36Sopenharmony_ci			f->add = false;
50062306a36Sopenharmony_ci			if (i == count)
50162306a36Sopenharmony_ci				break;
50262306a36Sopenharmony_ci		}
50362306a36Sopenharmony_ci	}
50462306a36Sopenharmony_ci	if (!more)
50562306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	spin_unlock_bh(&adapter->mac_vlan_list_lock);
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
51062306a36Sopenharmony_ci	kfree(veal);
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci/**
51462306a36Sopenharmony_ci * iavf_del_ether_addrs
51562306a36Sopenharmony_ci * @adapter: adapter structure
51662306a36Sopenharmony_ci *
51762306a36Sopenharmony_ci * Request that the PF remove one or more addresses from our filters.
51862306a36Sopenharmony_ci **/
51962306a36Sopenharmony_civoid iavf_del_ether_addrs(struct iavf_adapter *adapter)
52062306a36Sopenharmony_ci{
52162306a36Sopenharmony_ci	struct virtchnl_ether_addr_list *veal;
52262306a36Sopenharmony_ci	struct iavf_mac_filter *f, *ftmp;
52362306a36Sopenharmony_ci	int i = 0, count = 0;
52462306a36Sopenharmony_ci	bool more = false;
52562306a36Sopenharmony_ci	size_t len;
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
52862306a36Sopenharmony_ci		/* bail because we already have a command pending */
52962306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot remove filters, command %d pending\n",
53062306a36Sopenharmony_ci			adapter->current_op);
53162306a36Sopenharmony_ci		return;
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	list_for_each_entry(f, &adapter->mac_filter_list, list) {
53762306a36Sopenharmony_ci		if (f->remove)
53862306a36Sopenharmony_ci			count++;
53962306a36Sopenharmony_ci	}
54062306a36Sopenharmony_ci	if (!count) {
54162306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_MAC_FILTER;
54262306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
54362306a36Sopenharmony_ci		return;
54462306a36Sopenharmony_ci	}
54562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DEL_ETH_ADDR;
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci	len = virtchnl_struct_size(veal, list, count);
54862306a36Sopenharmony_ci	if (len > IAVF_MAX_AQ_BUF_SIZE) {
54962306a36Sopenharmony_ci		dev_warn(&adapter->pdev->dev, "Too many delete MAC changes in one request\n");
55062306a36Sopenharmony_ci		while (len > IAVF_MAX_AQ_BUF_SIZE)
55162306a36Sopenharmony_ci			len = virtchnl_struct_size(veal, list, --count);
55262306a36Sopenharmony_ci		more = true;
55362306a36Sopenharmony_ci	}
55462306a36Sopenharmony_ci	veal = kzalloc(len, GFP_ATOMIC);
55562306a36Sopenharmony_ci	if (!veal) {
55662306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
55762306a36Sopenharmony_ci		return;
55862306a36Sopenharmony_ci	}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	veal->vsi_id = adapter->vsi_res->vsi_id;
56162306a36Sopenharmony_ci	veal->num_elements = count;
56262306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
56362306a36Sopenharmony_ci		if (f->remove) {
56462306a36Sopenharmony_ci			ether_addr_copy(veal->list[i].addr, f->macaddr);
56562306a36Sopenharmony_ci			iavf_set_mac_addr_type(&veal->list[i], f);
56662306a36Sopenharmony_ci			i++;
56762306a36Sopenharmony_ci			list_del(&f->list);
56862306a36Sopenharmony_ci			kfree(f);
56962306a36Sopenharmony_ci			if (i == count)
57062306a36Sopenharmony_ci				break;
57162306a36Sopenharmony_ci		}
57262306a36Sopenharmony_ci	}
57362306a36Sopenharmony_ci	if (!more)
57462306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_MAC_FILTER;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	spin_unlock_bh(&adapter->mac_vlan_list_lock);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_ETH_ADDR, (u8 *)veal, len);
57962306a36Sopenharmony_ci	kfree(veal);
58062306a36Sopenharmony_ci}
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci/**
58362306a36Sopenharmony_ci * iavf_mac_add_ok
58462306a36Sopenharmony_ci * @adapter: adapter structure
58562306a36Sopenharmony_ci *
58662306a36Sopenharmony_ci * Submit list of filters based on PF response.
58762306a36Sopenharmony_ci **/
58862306a36Sopenharmony_cistatic void iavf_mac_add_ok(struct iavf_adapter *adapter)
58962306a36Sopenharmony_ci{
59062306a36Sopenharmony_ci	struct iavf_mac_filter *f, *ftmp;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
59362306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
59462306a36Sopenharmony_ci		f->is_new_mac = false;
59562306a36Sopenharmony_ci		if (!f->add && !f->add_handled)
59662306a36Sopenharmony_ci			f->add_handled = true;
59762306a36Sopenharmony_ci	}
59862306a36Sopenharmony_ci	spin_unlock_bh(&adapter->mac_vlan_list_lock);
59962306a36Sopenharmony_ci}
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci/**
60262306a36Sopenharmony_ci * iavf_mac_add_reject
60362306a36Sopenharmony_ci * @adapter: adapter structure
60462306a36Sopenharmony_ci *
60562306a36Sopenharmony_ci * Remove filters from list based on PF response.
60662306a36Sopenharmony_ci **/
60762306a36Sopenharmony_cistatic void iavf_mac_add_reject(struct iavf_adapter *adapter)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
61062306a36Sopenharmony_ci	struct iavf_mac_filter *f, *ftmp;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
61362306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
61462306a36Sopenharmony_ci		if (f->remove && ether_addr_equal(f->macaddr, netdev->dev_addr))
61562306a36Sopenharmony_ci			f->remove = false;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci		if (!f->add && !f->add_handled)
61862306a36Sopenharmony_ci			f->add_handled = true;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci		if (f->is_new_mac) {
62162306a36Sopenharmony_ci			list_del(&f->list);
62262306a36Sopenharmony_ci			kfree(f);
62362306a36Sopenharmony_ci		}
62462306a36Sopenharmony_ci	}
62562306a36Sopenharmony_ci	spin_unlock_bh(&adapter->mac_vlan_list_lock);
62662306a36Sopenharmony_ci}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci/**
62962306a36Sopenharmony_ci * iavf_vlan_add_reject
63062306a36Sopenharmony_ci * @adapter: adapter structure
63162306a36Sopenharmony_ci *
63262306a36Sopenharmony_ci * Remove VLAN filters from list based on PF response.
63362306a36Sopenharmony_ci **/
63462306a36Sopenharmony_cistatic void iavf_vlan_add_reject(struct iavf_adapter *adapter)
63562306a36Sopenharmony_ci{
63662306a36Sopenharmony_ci	struct iavf_vlan_filter *f, *ftmp;
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
63962306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
64062306a36Sopenharmony_ci		if (f->state == IAVF_VLAN_IS_NEW) {
64162306a36Sopenharmony_ci			list_del(&f->list);
64262306a36Sopenharmony_ci			kfree(f);
64362306a36Sopenharmony_ci			adapter->num_vlan_filters--;
64462306a36Sopenharmony_ci		}
64562306a36Sopenharmony_ci	}
64662306a36Sopenharmony_ci	spin_unlock_bh(&adapter->mac_vlan_list_lock);
64762306a36Sopenharmony_ci}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci/**
65062306a36Sopenharmony_ci * iavf_add_vlans
65162306a36Sopenharmony_ci * @adapter: adapter structure
65262306a36Sopenharmony_ci *
65362306a36Sopenharmony_ci * Request that the PF add one or more VLAN filters to our VSI.
65462306a36Sopenharmony_ci **/
65562306a36Sopenharmony_civoid iavf_add_vlans(struct iavf_adapter *adapter)
65662306a36Sopenharmony_ci{
65762306a36Sopenharmony_ci	int len, i = 0, count = 0;
65862306a36Sopenharmony_ci	struct iavf_vlan_filter *f;
65962306a36Sopenharmony_ci	bool more = false;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
66262306a36Sopenharmony_ci		/* bail because we already have a command pending */
66362306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot add VLANs, command %d pending\n",
66462306a36Sopenharmony_ci			adapter->current_op);
66562306a36Sopenharmony_ci		return;
66662306a36Sopenharmony_ci	}
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	list_for_each_entry(f, &adapter->vlan_filter_list, list) {
67162306a36Sopenharmony_ci		if (f->state == IAVF_VLAN_ADD)
67262306a36Sopenharmony_ci			count++;
67362306a36Sopenharmony_ci	}
67462306a36Sopenharmony_ci	if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
67562306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
67662306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
67762306a36Sopenharmony_ci		return;
67862306a36Sopenharmony_ci	}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	if (VLAN_ALLOWED(adapter)) {
68162306a36Sopenharmony_ci		struct virtchnl_vlan_filter_list *vvfl;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_ADD_VLAN;
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci		len = virtchnl_struct_size(vvfl, vlan_id, count);
68662306a36Sopenharmony_ci		if (len > IAVF_MAX_AQ_BUF_SIZE) {
68762306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
68862306a36Sopenharmony_ci			while (len > IAVF_MAX_AQ_BUF_SIZE)
68962306a36Sopenharmony_ci				len = virtchnl_struct_size(vvfl, vlan_id,
69062306a36Sopenharmony_ci							   --count);
69162306a36Sopenharmony_ci			more = true;
69262306a36Sopenharmony_ci		}
69362306a36Sopenharmony_ci		vvfl = kzalloc(len, GFP_ATOMIC);
69462306a36Sopenharmony_ci		if (!vvfl) {
69562306a36Sopenharmony_ci			spin_unlock_bh(&adapter->mac_vlan_list_lock);
69662306a36Sopenharmony_ci			return;
69762306a36Sopenharmony_ci		}
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci		vvfl->vsi_id = adapter->vsi_res->vsi_id;
70062306a36Sopenharmony_ci		vvfl->num_elements = count;
70162306a36Sopenharmony_ci		list_for_each_entry(f, &adapter->vlan_filter_list, list) {
70262306a36Sopenharmony_ci			if (f->state == IAVF_VLAN_ADD) {
70362306a36Sopenharmony_ci				vvfl->vlan_id[i] = f->vlan.vid;
70462306a36Sopenharmony_ci				i++;
70562306a36Sopenharmony_ci				f->state = IAVF_VLAN_IS_NEW;
70662306a36Sopenharmony_ci				if (i == count)
70762306a36Sopenharmony_ci					break;
70862306a36Sopenharmony_ci			}
70962306a36Sopenharmony_ci		}
71062306a36Sopenharmony_ci		if (!more)
71162306a36Sopenharmony_ci			adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
71662306a36Sopenharmony_ci		kfree(vvfl);
71762306a36Sopenharmony_ci	} else {
71862306a36Sopenharmony_ci		u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
71962306a36Sopenharmony_ci		u16 current_vlans = iavf_get_num_vlans_added(adapter);
72062306a36Sopenharmony_ci		struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci		if ((count + current_vlans) > max_vlans &&
72562306a36Sopenharmony_ci		    current_vlans < max_vlans) {
72662306a36Sopenharmony_ci			count = max_vlans - iavf_get_num_vlans_added(adapter);
72762306a36Sopenharmony_ci			more = true;
72862306a36Sopenharmony_ci		}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci		len = virtchnl_struct_size(vvfl_v2, filters, count);
73162306a36Sopenharmony_ci		if (len > IAVF_MAX_AQ_BUF_SIZE) {
73262306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
73362306a36Sopenharmony_ci			while (len > IAVF_MAX_AQ_BUF_SIZE)
73462306a36Sopenharmony_ci				len = virtchnl_struct_size(vvfl_v2, filters,
73562306a36Sopenharmony_ci							   --count);
73662306a36Sopenharmony_ci			more = true;
73762306a36Sopenharmony_ci		}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci		vvfl_v2 = kzalloc(len, GFP_ATOMIC);
74062306a36Sopenharmony_ci		if (!vvfl_v2) {
74162306a36Sopenharmony_ci			spin_unlock_bh(&adapter->mac_vlan_list_lock);
74262306a36Sopenharmony_ci			return;
74362306a36Sopenharmony_ci		}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci		vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
74662306a36Sopenharmony_ci		vvfl_v2->num_elements = count;
74762306a36Sopenharmony_ci		list_for_each_entry(f, &adapter->vlan_filter_list, list) {
74862306a36Sopenharmony_ci			if (f->state == IAVF_VLAN_ADD) {
74962306a36Sopenharmony_ci				struct virtchnl_vlan_supported_caps *filtering_support =
75062306a36Sopenharmony_ci					&adapter->vlan_v2_caps.filtering.filtering_support;
75162306a36Sopenharmony_ci				struct virtchnl_vlan *vlan;
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci				if (i == count)
75462306a36Sopenharmony_ci					break;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci				/* give priority over outer if it's enabled */
75762306a36Sopenharmony_ci				if (filtering_support->outer)
75862306a36Sopenharmony_ci					vlan = &vvfl_v2->filters[i].outer;
75962306a36Sopenharmony_ci				else
76062306a36Sopenharmony_ci					vlan = &vvfl_v2->filters[i].inner;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci				vlan->tci = f->vlan.vid;
76362306a36Sopenharmony_ci				vlan->tpid = f->vlan.tpid;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci				i++;
76662306a36Sopenharmony_ci				f->state = IAVF_VLAN_IS_NEW;
76762306a36Sopenharmony_ci			}
76862306a36Sopenharmony_ci		}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci		if (!more)
77162306a36Sopenharmony_ci			adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN_V2,
77662306a36Sopenharmony_ci				 (u8 *)vvfl_v2, len);
77762306a36Sopenharmony_ci		kfree(vvfl_v2);
77862306a36Sopenharmony_ci	}
77962306a36Sopenharmony_ci}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci/**
78262306a36Sopenharmony_ci * iavf_del_vlans
78362306a36Sopenharmony_ci * @adapter: adapter structure
78462306a36Sopenharmony_ci *
78562306a36Sopenharmony_ci * Request that the PF remove one or more VLAN filters from our VSI.
78662306a36Sopenharmony_ci **/
78762306a36Sopenharmony_civoid iavf_del_vlans(struct iavf_adapter *adapter)
78862306a36Sopenharmony_ci{
78962306a36Sopenharmony_ci	struct iavf_vlan_filter *f, *ftmp;
79062306a36Sopenharmony_ci	int len, i = 0, count = 0;
79162306a36Sopenharmony_ci	bool more = false;
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
79462306a36Sopenharmony_ci		/* bail because we already have a command pending */
79562306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot remove VLANs, command %d pending\n",
79662306a36Sopenharmony_ci			adapter->current_op);
79762306a36Sopenharmony_ci		return;
79862306a36Sopenharmony_ci	}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	spin_lock_bh(&adapter->mac_vlan_list_lock);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
80362306a36Sopenharmony_ci		/* since VLAN capabilities are not allowed, we dont want to send
80462306a36Sopenharmony_ci		 * a VLAN delete request because it will most likely fail and
80562306a36Sopenharmony_ci		 * create unnecessary errors/noise, so just free the VLAN
80662306a36Sopenharmony_ci		 * filters marked for removal to enable bailing out before
80762306a36Sopenharmony_ci		 * sending a virtchnl message
80862306a36Sopenharmony_ci		 */
80962306a36Sopenharmony_ci		if (f->state == IAVF_VLAN_REMOVE &&
81062306a36Sopenharmony_ci		    !VLAN_FILTERING_ALLOWED(adapter)) {
81162306a36Sopenharmony_ci			list_del(&f->list);
81262306a36Sopenharmony_ci			kfree(f);
81362306a36Sopenharmony_ci			adapter->num_vlan_filters--;
81462306a36Sopenharmony_ci		} else if (f->state == IAVF_VLAN_DISABLE &&
81562306a36Sopenharmony_ci		    !VLAN_FILTERING_ALLOWED(adapter)) {
81662306a36Sopenharmony_ci			f->state = IAVF_VLAN_INACTIVE;
81762306a36Sopenharmony_ci		} else if (f->state == IAVF_VLAN_REMOVE ||
81862306a36Sopenharmony_ci			   f->state == IAVF_VLAN_DISABLE) {
81962306a36Sopenharmony_ci			count++;
82062306a36Sopenharmony_ci		}
82162306a36Sopenharmony_ci	}
82262306a36Sopenharmony_ci	if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
82362306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
82462306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
82562306a36Sopenharmony_ci		return;
82662306a36Sopenharmony_ci	}
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	if (VLAN_ALLOWED(adapter)) {
82962306a36Sopenharmony_ci		struct virtchnl_vlan_filter_list *vvfl;
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_DEL_VLAN;
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci		len = virtchnl_struct_size(vvfl, vlan_id, count);
83462306a36Sopenharmony_ci		if (len > IAVF_MAX_AQ_BUF_SIZE) {
83562306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Too many delete VLAN changes in one request\n");
83662306a36Sopenharmony_ci			while (len > IAVF_MAX_AQ_BUF_SIZE)
83762306a36Sopenharmony_ci				len = virtchnl_struct_size(vvfl, vlan_id,
83862306a36Sopenharmony_ci							   --count);
83962306a36Sopenharmony_ci			more = true;
84062306a36Sopenharmony_ci		}
84162306a36Sopenharmony_ci		vvfl = kzalloc(len, GFP_ATOMIC);
84262306a36Sopenharmony_ci		if (!vvfl) {
84362306a36Sopenharmony_ci			spin_unlock_bh(&adapter->mac_vlan_list_lock);
84462306a36Sopenharmony_ci			return;
84562306a36Sopenharmony_ci		}
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci		vvfl->vsi_id = adapter->vsi_res->vsi_id;
84862306a36Sopenharmony_ci		vvfl->num_elements = count;
84962306a36Sopenharmony_ci		list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
85062306a36Sopenharmony_ci			if (f->state == IAVF_VLAN_DISABLE) {
85162306a36Sopenharmony_ci				vvfl->vlan_id[i] = f->vlan.vid;
85262306a36Sopenharmony_ci				f->state = IAVF_VLAN_INACTIVE;
85362306a36Sopenharmony_ci				i++;
85462306a36Sopenharmony_ci				if (i == count)
85562306a36Sopenharmony_ci					break;
85662306a36Sopenharmony_ci			} else if (f->state == IAVF_VLAN_REMOVE) {
85762306a36Sopenharmony_ci				vvfl->vlan_id[i] = f->vlan.vid;
85862306a36Sopenharmony_ci				list_del(&f->list);
85962306a36Sopenharmony_ci				kfree(f);
86062306a36Sopenharmony_ci				adapter->num_vlan_filters--;
86162306a36Sopenharmony_ci				i++;
86262306a36Sopenharmony_ci				if (i == count)
86362306a36Sopenharmony_ci					break;
86462306a36Sopenharmony_ci			}
86562306a36Sopenharmony_ci		}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci		if (!more)
86862306a36Sopenharmony_ci			adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
87362306a36Sopenharmony_ci		kfree(vvfl);
87462306a36Sopenharmony_ci	} else {
87562306a36Sopenharmony_ci		struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_DEL_VLAN_V2;
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci		len = virtchnl_struct_size(vvfl_v2, filters, count);
88062306a36Sopenharmony_ci		if (len > IAVF_MAX_AQ_BUF_SIZE) {
88162306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
88262306a36Sopenharmony_ci			while (len > IAVF_MAX_AQ_BUF_SIZE)
88362306a36Sopenharmony_ci				len = virtchnl_struct_size(vvfl_v2, filters,
88462306a36Sopenharmony_ci							   --count);
88562306a36Sopenharmony_ci			more = true;
88662306a36Sopenharmony_ci		}
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci		vvfl_v2 = kzalloc(len, GFP_ATOMIC);
88962306a36Sopenharmony_ci		if (!vvfl_v2) {
89062306a36Sopenharmony_ci			spin_unlock_bh(&adapter->mac_vlan_list_lock);
89162306a36Sopenharmony_ci			return;
89262306a36Sopenharmony_ci		}
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci		vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
89562306a36Sopenharmony_ci		vvfl_v2->num_elements = count;
89662306a36Sopenharmony_ci		list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
89762306a36Sopenharmony_ci			if (f->state == IAVF_VLAN_DISABLE ||
89862306a36Sopenharmony_ci			    f->state == IAVF_VLAN_REMOVE) {
89962306a36Sopenharmony_ci				struct virtchnl_vlan_supported_caps *filtering_support =
90062306a36Sopenharmony_ci					&adapter->vlan_v2_caps.filtering.filtering_support;
90162306a36Sopenharmony_ci				struct virtchnl_vlan *vlan;
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci				/* give priority over outer if it's enabled */
90462306a36Sopenharmony_ci				if (filtering_support->outer)
90562306a36Sopenharmony_ci					vlan = &vvfl_v2->filters[i].outer;
90662306a36Sopenharmony_ci				else
90762306a36Sopenharmony_ci					vlan = &vvfl_v2->filters[i].inner;
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_ci				vlan->tci = f->vlan.vid;
91062306a36Sopenharmony_ci				vlan->tpid = f->vlan.tpid;
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci				if (f->state == IAVF_VLAN_DISABLE) {
91362306a36Sopenharmony_ci					f->state = IAVF_VLAN_INACTIVE;
91462306a36Sopenharmony_ci				} else {
91562306a36Sopenharmony_ci					list_del(&f->list);
91662306a36Sopenharmony_ci					kfree(f);
91762306a36Sopenharmony_ci					adapter->num_vlan_filters--;
91862306a36Sopenharmony_ci				}
91962306a36Sopenharmony_ci				i++;
92062306a36Sopenharmony_ci				if (i == count)
92162306a36Sopenharmony_ci					break;
92262306a36Sopenharmony_ci			}
92362306a36Sopenharmony_ci		}
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci		if (!more)
92662306a36Sopenharmony_ci			adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_VLAN_V2,
93162306a36Sopenharmony_ci				 (u8 *)vvfl_v2, len);
93262306a36Sopenharmony_ci		kfree(vvfl_v2);
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci}
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci/**
93762306a36Sopenharmony_ci * iavf_set_promiscuous
93862306a36Sopenharmony_ci * @adapter: adapter structure
93962306a36Sopenharmony_ci *
94062306a36Sopenharmony_ci * Request that the PF enable promiscuous mode for our VSI.
94162306a36Sopenharmony_ci **/
94262306a36Sopenharmony_civoid iavf_set_promiscuous(struct iavf_adapter *adapter)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
94562306a36Sopenharmony_ci	struct virtchnl_promisc_info vpi;
94662306a36Sopenharmony_ci	unsigned int flags;
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
94962306a36Sopenharmony_ci		/* bail because we already have a command pending */
95062306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot set promiscuous mode, command %d pending\n",
95162306a36Sopenharmony_ci			adapter->current_op);
95262306a36Sopenharmony_ci		return;
95362306a36Sopenharmony_ci	}
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci	/* prevent changes to promiscuous flags */
95662306a36Sopenharmony_ci	spin_lock_bh(&adapter->current_netdev_promisc_flags_lock);
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci	/* sanity check to prevent duplicate AQ calls */
95962306a36Sopenharmony_ci	if (!iavf_promiscuous_mode_changed(adapter)) {
96062306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE;
96162306a36Sopenharmony_ci		dev_dbg(&adapter->pdev->dev, "No change in promiscuous mode\n");
96262306a36Sopenharmony_ci		/* allow changes to promiscuous flags */
96362306a36Sopenharmony_ci		spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock);
96462306a36Sopenharmony_ci		return;
96562306a36Sopenharmony_ci	}
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci	/* there are 2 bits, but only 3 states */
96862306a36Sopenharmony_ci	if (!(netdev->flags & IFF_PROMISC) &&
96962306a36Sopenharmony_ci	    netdev->flags & IFF_ALLMULTI) {
97062306a36Sopenharmony_ci		/* State 1  - only multicast promiscuous mode enabled
97162306a36Sopenharmony_ci		 * - !IFF_PROMISC && IFF_ALLMULTI
97262306a36Sopenharmony_ci		 */
97362306a36Sopenharmony_ci		flags = FLAG_VF_MULTICAST_PROMISC;
97462306a36Sopenharmony_ci		adapter->current_netdev_promisc_flags |= IFF_ALLMULTI;
97562306a36Sopenharmony_ci		adapter->current_netdev_promisc_flags &= ~IFF_PROMISC;
97662306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "Entering multicast promiscuous mode\n");
97762306a36Sopenharmony_ci	} else if (!(netdev->flags & IFF_PROMISC) &&
97862306a36Sopenharmony_ci		   !(netdev->flags & IFF_ALLMULTI)) {
97962306a36Sopenharmony_ci		/* State 2 - unicast/multicast promiscuous mode disabled
98062306a36Sopenharmony_ci		 * - !IFF_PROMISC && !IFF_ALLMULTI
98162306a36Sopenharmony_ci		 */
98262306a36Sopenharmony_ci		flags = 0;
98362306a36Sopenharmony_ci		adapter->current_netdev_promisc_flags &=
98462306a36Sopenharmony_ci			~(IFF_PROMISC | IFF_ALLMULTI);
98562306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n");
98662306a36Sopenharmony_ci	} else {
98762306a36Sopenharmony_ci		/* State 3 - unicast/multicast promiscuous mode enabled
98862306a36Sopenharmony_ci		 * - IFF_PROMISC && IFF_ALLMULTI
98962306a36Sopenharmony_ci		 * - IFF_PROMISC && !IFF_ALLMULTI
99062306a36Sopenharmony_ci		 */
99162306a36Sopenharmony_ci		flags = FLAG_VF_UNICAST_PROMISC | FLAG_VF_MULTICAST_PROMISC;
99262306a36Sopenharmony_ci		adapter->current_netdev_promisc_flags |= IFF_PROMISC;
99362306a36Sopenharmony_ci		if (netdev->flags & IFF_ALLMULTI)
99462306a36Sopenharmony_ci			adapter->current_netdev_promisc_flags |= IFF_ALLMULTI;
99562306a36Sopenharmony_ci		else
99662306a36Sopenharmony_ci			adapter->current_netdev_promisc_flags &= ~IFF_ALLMULTI;
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n");
99962306a36Sopenharmony_ci	}
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE;
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	/* allow changes to promiscuous flags */
100462306a36Sopenharmony_ci	spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock);
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
100762306a36Sopenharmony_ci	vpi.vsi_id = adapter->vsi_res->vsi_id;
100862306a36Sopenharmony_ci	vpi.flags = flags;
100962306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
101062306a36Sopenharmony_ci			 (u8 *)&vpi, sizeof(vpi));
101162306a36Sopenharmony_ci}
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci/**
101462306a36Sopenharmony_ci * iavf_request_stats
101562306a36Sopenharmony_ci * @adapter: adapter structure
101662306a36Sopenharmony_ci *
101762306a36Sopenharmony_ci * Request VSI statistics from PF.
101862306a36Sopenharmony_ci **/
101962306a36Sopenharmony_civoid iavf_request_stats(struct iavf_adapter *adapter)
102062306a36Sopenharmony_ci{
102162306a36Sopenharmony_ci	struct virtchnl_queue_select vqs;
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
102462306a36Sopenharmony_ci		/* no error message, this isn't crucial */
102562306a36Sopenharmony_ci		return;
102662306a36Sopenharmony_ci	}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_STATS;
102962306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_GET_STATS;
103062306a36Sopenharmony_ci	vqs.vsi_id = adapter->vsi_res->vsi_id;
103162306a36Sopenharmony_ci	/* queue maps are ignored for this message - only the vsi is used */
103262306a36Sopenharmony_ci	if (iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_STATS, (u8 *)&vqs,
103362306a36Sopenharmony_ci			     sizeof(vqs)))
103462306a36Sopenharmony_ci		/* if the request failed, don't lock out others */
103562306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_UNKNOWN;
103662306a36Sopenharmony_ci}
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ci/**
103962306a36Sopenharmony_ci * iavf_get_hena
104062306a36Sopenharmony_ci * @adapter: adapter structure
104162306a36Sopenharmony_ci *
104262306a36Sopenharmony_ci * Request hash enable capabilities from PF
104362306a36Sopenharmony_ci **/
104462306a36Sopenharmony_civoid iavf_get_hena(struct iavf_adapter *adapter)
104562306a36Sopenharmony_ci{
104662306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
104762306a36Sopenharmony_ci		/* bail because we already have a command pending */
104862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot get RSS hash capabilities, command %d pending\n",
104962306a36Sopenharmony_ci			adapter->current_op);
105062306a36Sopenharmony_ci		return;
105162306a36Sopenharmony_ci	}
105262306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_GET_RSS_HENA_CAPS;
105362306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_GET_HENA;
105462306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_RSS_HENA_CAPS, NULL, 0);
105562306a36Sopenharmony_ci}
105662306a36Sopenharmony_ci
105762306a36Sopenharmony_ci/**
105862306a36Sopenharmony_ci * iavf_set_hena
105962306a36Sopenharmony_ci * @adapter: adapter structure
106062306a36Sopenharmony_ci *
106162306a36Sopenharmony_ci * Request the PF to set our RSS hash capabilities
106262306a36Sopenharmony_ci **/
106362306a36Sopenharmony_civoid iavf_set_hena(struct iavf_adapter *adapter)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	struct virtchnl_rss_hena vrh;
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
106862306a36Sopenharmony_ci		/* bail because we already have a command pending */
106962306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot set RSS hash enable, command %d pending\n",
107062306a36Sopenharmony_ci			adapter->current_op);
107162306a36Sopenharmony_ci		return;
107262306a36Sopenharmony_ci	}
107362306a36Sopenharmony_ci	vrh.hena = adapter->hena;
107462306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_SET_RSS_HENA;
107562306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_SET_HENA;
107662306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_SET_RSS_HENA, (u8 *)&vrh,
107762306a36Sopenharmony_ci			 sizeof(vrh));
107862306a36Sopenharmony_ci}
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci/**
108162306a36Sopenharmony_ci * iavf_set_rss_key
108262306a36Sopenharmony_ci * @adapter: adapter structure
108362306a36Sopenharmony_ci *
108462306a36Sopenharmony_ci * Request the PF to set our RSS hash key
108562306a36Sopenharmony_ci **/
108662306a36Sopenharmony_civoid iavf_set_rss_key(struct iavf_adapter *adapter)
108762306a36Sopenharmony_ci{
108862306a36Sopenharmony_ci	struct virtchnl_rss_key *vrk;
108962306a36Sopenharmony_ci	int len;
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
109262306a36Sopenharmony_ci		/* bail because we already have a command pending */
109362306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot set RSS key, command %d pending\n",
109462306a36Sopenharmony_ci			adapter->current_op);
109562306a36Sopenharmony_ci		return;
109662306a36Sopenharmony_ci	}
109762306a36Sopenharmony_ci	len = virtchnl_struct_size(vrk, key, adapter->rss_key_size);
109862306a36Sopenharmony_ci	vrk = kzalloc(len, GFP_KERNEL);
109962306a36Sopenharmony_ci	if (!vrk)
110062306a36Sopenharmony_ci		return;
110162306a36Sopenharmony_ci	vrk->vsi_id = adapter->vsi.id;
110262306a36Sopenharmony_ci	vrk->key_len = adapter->rss_key_size;
110362306a36Sopenharmony_ci	memcpy(vrk->key, adapter->rss_key, adapter->rss_key_size);
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_CONFIG_RSS_KEY;
110662306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_SET_RSS_KEY;
110762306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_RSS_KEY, (u8 *)vrk, len);
110862306a36Sopenharmony_ci	kfree(vrk);
110962306a36Sopenharmony_ci}
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci/**
111262306a36Sopenharmony_ci * iavf_set_rss_lut
111362306a36Sopenharmony_ci * @adapter: adapter structure
111462306a36Sopenharmony_ci *
111562306a36Sopenharmony_ci * Request the PF to set our RSS lookup table
111662306a36Sopenharmony_ci **/
111762306a36Sopenharmony_civoid iavf_set_rss_lut(struct iavf_adapter *adapter)
111862306a36Sopenharmony_ci{
111962306a36Sopenharmony_ci	struct virtchnl_rss_lut *vrl;
112062306a36Sopenharmony_ci	int len;
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
112362306a36Sopenharmony_ci		/* bail because we already have a command pending */
112462306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot set RSS LUT, command %d pending\n",
112562306a36Sopenharmony_ci			adapter->current_op);
112662306a36Sopenharmony_ci		return;
112762306a36Sopenharmony_ci	}
112862306a36Sopenharmony_ci	len = virtchnl_struct_size(vrl, lut, adapter->rss_lut_size);
112962306a36Sopenharmony_ci	vrl = kzalloc(len, GFP_KERNEL);
113062306a36Sopenharmony_ci	if (!vrl)
113162306a36Sopenharmony_ci		return;
113262306a36Sopenharmony_ci	vrl->vsi_id = adapter->vsi.id;
113362306a36Sopenharmony_ci	vrl->lut_entries = adapter->rss_lut_size;
113462306a36Sopenharmony_ci	memcpy(vrl->lut, adapter->rss_lut, adapter->rss_lut_size);
113562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_CONFIG_RSS_LUT;
113662306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_SET_RSS_LUT;
113762306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_RSS_LUT, (u8 *)vrl, len);
113862306a36Sopenharmony_ci	kfree(vrl);
113962306a36Sopenharmony_ci}
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci/**
114262306a36Sopenharmony_ci * iavf_enable_vlan_stripping
114362306a36Sopenharmony_ci * @adapter: adapter structure
114462306a36Sopenharmony_ci *
114562306a36Sopenharmony_ci * Request VLAN header stripping to be enabled
114662306a36Sopenharmony_ci **/
114762306a36Sopenharmony_civoid iavf_enable_vlan_stripping(struct iavf_adapter *adapter)
114862306a36Sopenharmony_ci{
114962306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
115062306a36Sopenharmony_ci		/* bail because we already have a command pending */
115162306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot enable stripping, command %d pending\n",
115262306a36Sopenharmony_ci			adapter->current_op);
115362306a36Sopenharmony_ci		return;
115462306a36Sopenharmony_ci	}
115562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
115662306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING;
115762306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, NULL, 0);
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ci/**
116162306a36Sopenharmony_ci * iavf_disable_vlan_stripping
116262306a36Sopenharmony_ci * @adapter: adapter structure
116362306a36Sopenharmony_ci *
116462306a36Sopenharmony_ci * Request VLAN header stripping to be disabled
116562306a36Sopenharmony_ci **/
116662306a36Sopenharmony_civoid iavf_disable_vlan_stripping(struct iavf_adapter *adapter)
116762306a36Sopenharmony_ci{
116862306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
116962306a36Sopenharmony_ci		/* bail because we already have a command pending */
117062306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot disable stripping, command %d pending\n",
117162306a36Sopenharmony_ci			adapter->current_op);
117262306a36Sopenharmony_ci		return;
117362306a36Sopenharmony_ci	}
117462306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
117562306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING;
117662306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, NULL, 0);
117762306a36Sopenharmony_ci}
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci/**
118062306a36Sopenharmony_ci * iavf_tpid_to_vc_ethertype - transform from VLAN TPID to virtchnl ethertype
118162306a36Sopenharmony_ci * @tpid: VLAN TPID (i.e. 0x8100, 0x88a8, etc.)
118262306a36Sopenharmony_ci */
118362306a36Sopenharmony_cistatic u32 iavf_tpid_to_vc_ethertype(u16 tpid)
118462306a36Sopenharmony_ci{
118562306a36Sopenharmony_ci	switch (tpid) {
118662306a36Sopenharmony_ci	case ETH_P_8021Q:
118762306a36Sopenharmony_ci		return VIRTCHNL_VLAN_ETHERTYPE_8100;
118862306a36Sopenharmony_ci	case ETH_P_8021AD:
118962306a36Sopenharmony_ci		return VIRTCHNL_VLAN_ETHERTYPE_88A8;
119062306a36Sopenharmony_ci	}
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	return 0;
119362306a36Sopenharmony_ci}
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_ci/**
119662306a36Sopenharmony_ci * iavf_set_vc_offload_ethertype - set virtchnl ethertype for offload message
119762306a36Sopenharmony_ci * @adapter: adapter structure
119862306a36Sopenharmony_ci * @msg: message structure used for updating offloads over virtchnl to update
119962306a36Sopenharmony_ci * @tpid: VLAN TPID (i.e. 0x8100, 0x88a8, etc.)
120062306a36Sopenharmony_ci * @offload_op: opcode used to determine which support structure to check
120162306a36Sopenharmony_ci */
120262306a36Sopenharmony_cistatic int
120362306a36Sopenharmony_ciiavf_set_vc_offload_ethertype(struct iavf_adapter *adapter,
120462306a36Sopenharmony_ci			      struct virtchnl_vlan_setting *msg, u16 tpid,
120562306a36Sopenharmony_ci			      enum virtchnl_ops offload_op)
120662306a36Sopenharmony_ci{
120762306a36Sopenharmony_ci	struct virtchnl_vlan_supported_caps *offload_support;
120862306a36Sopenharmony_ci	u16 vc_ethertype = iavf_tpid_to_vc_ethertype(tpid);
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci	/* reference the correct offload support structure */
121162306a36Sopenharmony_ci	switch (offload_op) {
121262306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2:
121362306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2:
121462306a36Sopenharmony_ci		offload_support =
121562306a36Sopenharmony_ci			&adapter->vlan_v2_caps.offloads.stripping_support;
121662306a36Sopenharmony_ci		break;
121762306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2:
121862306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2:
121962306a36Sopenharmony_ci		offload_support =
122062306a36Sopenharmony_ci			&adapter->vlan_v2_caps.offloads.insertion_support;
122162306a36Sopenharmony_ci		break;
122262306a36Sopenharmony_ci	default:
122362306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Invalid opcode %d for setting virtchnl ethertype to enable/disable VLAN offloads\n",
122462306a36Sopenharmony_ci			offload_op);
122562306a36Sopenharmony_ci		return -EINVAL;
122662306a36Sopenharmony_ci	}
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	/* make sure ethertype is supported */
122962306a36Sopenharmony_ci	if (offload_support->outer & vc_ethertype &&
123062306a36Sopenharmony_ci	    offload_support->outer & VIRTCHNL_VLAN_TOGGLE) {
123162306a36Sopenharmony_ci		msg->outer_ethertype_setting = vc_ethertype;
123262306a36Sopenharmony_ci	} else if (offload_support->inner & vc_ethertype &&
123362306a36Sopenharmony_ci		   offload_support->inner & VIRTCHNL_VLAN_TOGGLE) {
123462306a36Sopenharmony_ci		msg->inner_ethertype_setting = vc_ethertype;
123562306a36Sopenharmony_ci	} else {
123662306a36Sopenharmony_ci		dev_dbg(&adapter->pdev->dev, "opcode %d unsupported for VLAN TPID 0x%04x\n",
123762306a36Sopenharmony_ci			offload_op, tpid);
123862306a36Sopenharmony_ci		return -EINVAL;
123962306a36Sopenharmony_ci	}
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	return 0;
124262306a36Sopenharmony_ci}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci/**
124562306a36Sopenharmony_ci * iavf_clear_offload_v2_aq_required - clear AQ required bit for offload request
124662306a36Sopenharmony_ci * @adapter: adapter structure
124762306a36Sopenharmony_ci * @tpid: VLAN TPID
124862306a36Sopenharmony_ci * @offload_op: opcode used to determine which AQ required bit to clear
124962306a36Sopenharmony_ci */
125062306a36Sopenharmony_cistatic void
125162306a36Sopenharmony_ciiavf_clear_offload_v2_aq_required(struct iavf_adapter *adapter, u16 tpid,
125262306a36Sopenharmony_ci				  enum virtchnl_ops offload_op)
125362306a36Sopenharmony_ci{
125462306a36Sopenharmony_ci	switch (offload_op) {
125562306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2:
125662306a36Sopenharmony_ci		if (tpid == ETH_P_8021Q)
125762306a36Sopenharmony_ci			adapter->aq_required &=
125862306a36Sopenharmony_ci				~IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING;
125962306a36Sopenharmony_ci		else if (tpid == ETH_P_8021AD)
126062306a36Sopenharmony_ci			adapter->aq_required &=
126162306a36Sopenharmony_ci				~IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING;
126262306a36Sopenharmony_ci		break;
126362306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2:
126462306a36Sopenharmony_ci		if (tpid == ETH_P_8021Q)
126562306a36Sopenharmony_ci			adapter->aq_required &=
126662306a36Sopenharmony_ci				~IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING;
126762306a36Sopenharmony_ci		else if (tpid == ETH_P_8021AD)
126862306a36Sopenharmony_ci			adapter->aq_required &=
126962306a36Sopenharmony_ci				~IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING;
127062306a36Sopenharmony_ci		break;
127162306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2:
127262306a36Sopenharmony_ci		if (tpid == ETH_P_8021Q)
127362306a36Sopenharmony_ci			adapter->aq_required &=
127462306a36Sopenharmony_ci				~IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION;
127562306a36Sopenharmony_ci		else if (tpid == ETH_P_8021AD)
127662306a36Sopenharmony_ci			adapter->aq_required &=
127762306a36Sopenharmony_ci				~IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION;
127862306a36Sopenharmony_ci		break;
127962306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2:
128062306a36Sopenharmony_ci		if (tpid == ETH_P_8021Q)
128162306a36Sopenharmony_ci			adapter->aq_required &=
128262306a36Sopenharmony_ci				~IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION;
128362306a36Sopenharmony_ci		else if (tpid == ETH_P_8021AD)
128462306a36Sopenharmony_ci			adapter->aq_required &=
128562306a36Sopenharmony_ci				~IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION;
128662306a36Sopenharmony_ci		break;
128762306a36Sopenharmony_ci	default:
128862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Unsupported opcode %d specified for clearing aq_required bits for VIRTCHNL_VF_OFFLOAD_VLAN_V2 offload request\n",
128962306a36Sopenharmony_ci			offload_op);
129062306a36Sopenharmony_ci	}
129162306a36Sopenharmony_ci}
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci/**
129462306a36Sopenharmony_ci * iavf_send_vlan_offload_v2 - send offload enable/disable over virtchnl
129562306a36Sopenharmony_ci * @adapter: adapter structure
129662306a36Sopenharmony_ci * @tpid: VLAN TPID used for the command (i.e. 0x8100 or 0x88a8)
129762306a36Sopenharmony_ci * @offload_op: offload_op used to make the request over virtchnl
129862306a36Sopenharmony_ci */
129962306a36Sopenharmony_cistatic void
130062306a36Sopenharmony_ciiavf_send_vlan_offload_v2(struct iavf_adapter *adapter, u16 tpid,
130162306a36Sopenharmony_ci			  enum virtchnl_ops offload_op)
130262306a36Sopenharmony_ci{
130362306a36Sopenharmony_ci	struct virtchnl_vlan_setting *msg;
130462306a36Sopenharmony_ci	int len = sizeof(*msg);
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
130762306a36Sopenharmony_ci		/* bail because we already have a command pending */
130862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot send %d, command %d pending\n",
130962306a36Sopenharmony_ci			offload_op, adapter->current_op);
131062306a36Sopenharmony_ci		return;
131162306a36Sopenharmony_ci	}
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	adapter->current_op = offload_op;
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci	msg = kzalloc(len, GFP_KERNEL);
131662306a36Sopenharmony_ci	if (!msg)
131762306a36Sopenharmony_ci		return;
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	msg->vport_id = adapter->vsi_res->vsi_id;
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	/* always clear to prevent unsupported and endless requests */
132262306a36Sopenharmony_ci	iavf_clear_offload_v2_aq_required(adapter, tpid, offload_op);
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	/* only send valid offload requests */
132562306a36Sopenharmony_ci	if (!iavf_set_vc_offload_ethertype(adapter, msg, tpid, offload_op))
132662306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, offload_op, (u8 *)msg, len);
132762306a36Sopenharmony_ci	else
132862306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_UNKNOWN;
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci	kfree(msg);
133162306a36Sopenharmony_ci}
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci/**
133462306a36Sopenharmony_ci * iavf_enable_vlan_stripping_v2 - enable VLAN stripping
133562306a36Sopenharmony_ci * @adapter: adapter structure
133662306a36Sopenharmony_ci * @tpid: VLAN TPID used to enable VLAN stripping
133762306a36Sopenharmony_ci */
133862306a36Sopenharmony_civoid iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid)
133962306a36Sopenharmony_ci{
134062306a36Sopenharmony_ci	iavf_send_vlan_offload_v2(adapter, tpid,
134162306a36Sopenharmony_ci				  VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2);
134262306a36Sopenharmony_ci}
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci/**
134562306a36Sopenharmony_ci * iavf_disable_vlan_stripping_v2 - disable VLAN stripping
134662306a36Sopenharmony_ci * @adapter: adapter structure
134762306a36Sopenharmony_ci * @tpid: VLAN TPID used to disable VLAN stripping
134862306a36Sopenharmony_ci */
134962306a36Sopenharmony_civoid iavf_disable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid)
135062306a36Sopenharmony_ci{
135162306a36Sopenharmony_ci	iavf_send_vlan_offload_v2(adapter, tpid,
135262306a36Sopenharmony_ci				  VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2);
135362306a36Sopenharmony_ci}
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci/**
135662306a36Sopenharmony_ci * iavf_enable_vlan_insertion_v2 - enable VLAN insertion
135762306a36Sopenharmony_ci * @adapter: adapter structure
135862306a36Sopenharmony_ci * @tpid: VLAN TPID used to enable VLAN insertion
135962306a36Sopenharmony_ci */
136062306a36Sopenharmony_civoid iavf_enable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid)
136162306a36Sopenharmony_ci{
136262306a36Sopenharmony_ci	iavf_send_vlan_offload_v2(adapter, tpid,
136362306a36Sopenharmony_ci				  VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2);
136462306a36Sopenharmony_ci}
136562306a36Sopenharmony_ci
136662306a36Sopenharmony_ci/**
136762306a36Sopenharmony_ci * iavf_disable_vlan_insertion_v2 - disable VLAN insertion
136862306a36Sopenharmony_ci * @adapter: adapter structure
136962306a36Sopenharmony_ci * @tpid: VLAN TPID used to disable VLAN insertion
137062306a36Sopenharmony_ci */
137162306a36Sopenharmony_civoid iavf_disable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid)
137262306a36Sopenharmony_ci{
137362306a36Sopenharmony_ci	iavf_send_vlan_offload_v2(adapter, tpid,
137462306a36Sopenharmony_ci				  VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2);
137562306a36Sopenharmony_ci}
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci#define IAVF_MAX_SPEED_STRLEN	13
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_ci/**
138062306a36Sopenharmony_ci * iavf_print_link_message - print link up or down
138162306a36Sopenharmony_ci * @adapter: adapter structure
138262306a36Sopenharmony_ci *
138362306a36Sopenharmony_ci * Log a message telling the world of our wonderous link status
138462306a36Sopenharmony_ci */
138562306a36Sopenharmony_cistatic void iavf_print_link_message(struct iavf_adapter *adapter)
138662306a36Sopenharmony_ci{
138762306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
138862306a36Sopenharmony_ci	int link_speed_mbps;
138962306a36Sopenharmony_ci	char *speed;
139062306a36Sopenharmony_ci
139162306a36Sopenharmony_ci	if (!adapter->link_up) {
139262306a36Sopenharmony_ci		netdev_info(netdev, "NIC Link is Down\n");
139362306a36Sopenharmony_ci		return;
139462306a36Sopenharmony_ci	}
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	speed = kzalloc(IAVF_MAX_SPEED_STRLEN, GFP_KERNEL);
139762306a36Sopenharmony_ci	if (!speed)
139862306a36Sopenharmony_ci		return;
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	if (ADV_LINK_SUPPORT(adapter)) {
140162306a36Sopenharmony_ci		link_speed_mbps = adapter->link_speed_mbps;
140262306a36Sopenharmony_ci		goto print_link_msg;
140362306a36Sopenharmony_ci	}
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	switch (adapter->link_speed) {
140662306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_40GB:
140762306a36Sopenharmony_ci		link_speed_mbps = SPEED_40000;
140862306a36Sopenharmony_ci		break;
140962306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_25GB:
141062306a36Sopenharmony_ci		link_speed_mbps = SPEED_25000;
141162306a36Sopenharmony_ci		break;
141262306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_20GB:
141362306a36Sopenharmony_ci		link_speed_mbps = SPEED_20000;
141462306a36Sopenharmony_ci		break;
141562306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_10GB:
141662306a36Sopenharmony_ci		link_speed_mbps = SPEED_10000;
141762306a36Sopenharmony_ci		break;
141862306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_5GB:
141962306a36Sopenharmony_ci		link_speed_mbps = SPEED_5000;
142062306a36Sopenharmony_ci		break;
142162306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_2_5GB:
142262306a36Sopenharmony_ci		link_speed_mbps = SPEED_2500;
142362306a36Sopenharmony_ci		break;
142462306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_1GB:
142562306a36Sopenharmony_ci		link_speed_mbps = SPEED_1000;
142662306a36Sopenharmony_ci		break;
142762306a36Sopenharmony_ci	case VIRTCHNL_LINK_SPEED_100MB:
142862306a36Sopenharmony_ci		link_speed_mbps = SPEED_100;
142962306a36Sopenharmony_ci		break;
143062306a36Sopenharmony_ci	default:
143162306a36Sopenharmony_ci		link_speed_mbps = SPEED_UNKNOWN;
143262306a36Sopenharmony_ci		break;
143362306a36Sopenharmony_ci	}
143462306a36Sopenharmony_ci
143562306a36Sopenharmony_ciprint_link_msg:
143662306a36Sopenharmony_ci	if (link_speed_mbps > SPEED_1000) {
143762306a36Sopenharmony_ci		if (link_speed_mbps == SPEED_2500)
143862306a36Sopenharmony_ci			snprintf(speed, IAVF_MAX_SPEED_STRLEN, "2.5 Gbps");
143962306a36Sopenharmony_ci		else
144062306a36Sopenharmony_ci			/* convert to Gbps inline */
144162306a36Sopenharmony_ci			snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s",
144262306a36Sopenharmony_ci				 link_speed_mbps / 1000, "Gbps");
144362306a36Sopenharmony_ci	} else if (link_speed_mbps == SPEED_UNKNOWN) {
144462306a36Sopenharmony_ci		snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%s", "Unknown Mbps");
144562306a36Sopenharmony_ci	} else {
144662306a36Sopenharmony_ci		snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s",
144762306a36Sopenharmony_ci			 link_speed_mbps, "Mbps");
144862306a36Sopenharmony_ci	}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	netdev_info(netdev, "NIC Link is Up Speed is %s Full Duplex\n", speed);
145162306a36Sopenharmony_ci	kfree(speed);
145262306a36Sopenharmony_ci}
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci/**
145562306a36Sopenharmony_ci * iavf_get_vpe_link_status
145662306a36Sopenharmony_ci * @adapter: adapter structure
145762306a36Sopenharmony_ci * @vpe: virtchnl_pf_event structure
145862306a36Sopenharmony_ci *
145962306a36Sopenharmony_ci * Helper function for determining the link status
146062306a36Sopenharmony_ci **/
146162306a36Sopenharmony_cistatic bool
146262306a36Sopenharmony_ciiavf_get_vpe_link_status(struct iavf_adapter *adapter,
146362306a36Sopenharmony_ci			 struct virtchnl_pf_event *vpe)
146462306a36Sopenharmony_ci{
146562306a36Sopenharmony_ci	if (ADV_LINK_SUPPORT(adapter))
146662306a36Sopenharmony_ci		return vpe->event_data.link_event_adv.link_status;
146762306a36Sopenharmony_ci	else
146862306a36Sopenharmony_ci		return vpe->event_data.link_event.link_status;
146962306a36Sopenharmony_ci}
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci/**
147262306a36Sopenharmony_ci * iavf_set_adapter_link_speed_from_vpe
147362306a36Sopenharmony_ci * @adapter: adapter structure for which we are setting the link speed
147462306a36Sopenharmony_ci * @vpe: virtchnl_pf_event structure that contains the link speed we are setting
147562306a36Sopenharmony_ci *
147662306a36Sopenharmony_ci * Helper function for setting iavf_adapter link speed
147762306a36Sopenharmony_ci **/
147862306a36Sopenharmony_cistatic void
147962306a36Sopenharmony_ciiavf_set_adapter_link_speed_from_vpe(struct iavf_adapter *adapter,
148062306a36Sopenharmony_ci				     struct virtchnl_pf_event *vpe)
148162306a36Sopenharmony_ci{
148262306a36Sopenharmony_ci	if (ADV_LINK_SUPPORT(adapter))
148362306a36Sopenharmony_ci		adapter->link_speed_mbps =
148462306a36Sopenharmony_ci			vpe->event_data.link_event_adv.link_speed;
148562306a36Sopenharmony_ci	else
148662306a36Sopenharmony_ci		adapter->link_speed = vpe->event_data.link_event.link_speed;
148762306a36Sopenharmony_ci}
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci/**
149062306a36Sopenharmony_ci * iavf_enable_channels
149162306a36Sopenharmony_ci * @adapter: adapter structure
149262306a36Sopenharmony_ci *
149362306a36Sopenharmony_ci * Request that the PF enable channels as specified by
149462306a36Sopenharmony_ci * the user via tc tool.
149562306a36Sopenharmony_ci **/
149662306a36Sopenharmony_civoid iavf_enable_channels(struct iavf_adapter *adapter)
149762306a36Sopenharmony_ci{
149862306a36Sopenharmony_ci	struct virtchnl_tc_info *vti = NULL;
149962306a36Sopenharmony_ci	size_t len;
150062306a36Sopenharmony_ci	int i;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
150362306a36Sopenharmony_ci		/* bail because we already have a command pending */
150462306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
150562306a36Sopenharmony_ci			adapter->current_op);
150662306a36Sopenharmony_ci		return;
150762306a36Sopenharmony_ci	}
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_ci	len = virtchnl_struct_size(vti, list, adapter->num_tc);
151062306a36Sopenharmony_ci	vti = kzalloc(len, GFP_KERNEL);
151162306a36Sopenharmony_ci	if (!vti)
151262306a36Sopenharmony_ci		return;
151362306a36Sopenharmony_ci	vti->num_tc = adapter->num_tc;
151462306a36Sopenharmony_ci	for (i = 0; i < vti->num_tc; i++) {
151562306a36Sopenharmony_ci		vti->list[i].count = adapter->ch_config.ch_info[i].count;
151662306a36Sopenharmony_ci		vti->list[i].offset = adapter->ch_config.ch_info[i].offset;
151762306a36Sopenharmony_ci		vti->list[i].pad = 0;
151862306a36Sopenharmony_ci		vti->list[i].max_tx_rate =
151962306a36Sopenharmony_ci				adapter->ch_config.ch_info[i].max_tx_rate;
152062306a36Sopenharmony_ci	}
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	adapter->ch_config.state = __IAVF_TC_RUNNING;
152362306a36Sopenharmony_ci	adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
152462306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ENABLE_CHANNELS;
152562306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_CHANNELS;
152662306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_CHANNELS, (u8 *)vti, len);
152762306a36Sopenharmony_ci	kfree(vti);
152862306a36Sopenharmony_ci}
152962306a36Sopenharmony_ci
153062306a36Sopenharmony_ci/**
153162306a36Sopenharmony_ci * iavf_disable_channels
153262306a36Sopenharmony_ci * @adapter: adapter structure
153362306a36Sopenharmony_ci *
153462306a36Sopenharmony_ci * Request that the PF disable channels that are configured
153562306a36Sopenharmony_ci **/
153662306a36Sopenharmony_civoid iavf_disable_channels(struct iavf_adapter *adapter)
153762306a36Sopenharmony_ci{
153862306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
153962306a36Sopenharmony_ci		/* bail because we already have a command pending */
154062306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
154162306a36Sopenharmony_ci			adapter->current_op);
154262306a36Sopenharmony_ci		return;
154362306a36Sopenharmony_ci	}
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	adapter->ch_config.state = __IAVF_TC_INVALID;
154662306a36Sopenharmony_ci	adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
154762306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DISABLE_CHANNELS;
154862306a36Sopenharmony_ci	adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_CHANNELS;
154962306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_CHANNELS, NULL, 0);
155062306a36Sopenharmony_ci}
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci/**
155362306a36Sopenharmony_ci * iavf_print_cloud_filter
155462306a36Sopenharmony_ci * @adapter: adapter structure
155562306a36Sopenharmony_ci * @f: cloud filter to print
155662306a36Sopenharmony_ci *
155762306a36Sopenharmony_ci * Print the cloud filter
155862306a36Sopenharmony_ci **/
155962306a36Sopenharmony_cistatic void iavf_print_cloud_filter(struct iavf_adapter *adapter,
156062306a36Sopenharmony_ci				    struct virtchnl_filter *f)
156162306a36Sopenharmony_ci{
156262306a36Sopenharmony_ci	switch (f->flow_type) {
156362306a36Sopenharmony_ci	case VIRTCHNL_TCP_V4_FLOW:
156462306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "dst_mac: %pM src_mac: %pM vlan_id: %hu dst_ip: %pI4 src_ip %pI4 dst_port %hu src_port %hu\n",
156562306a36Sopenharmony_ci			 &f->data.tcp_spec.dst_mac,
156662306a36Sopenharmony_ci			 &f->data.tcp_spec.src_mac,
156762306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.vlan_id),
156862306a36Sopenharmony_ci			 &f->data.tcp_spec.dst_ip[0],
156962306a36Sopenharmony_ci			 &f->data.tcp_spec.src_ip[0],
157062306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.dst_port),
157162306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.src_port));
157262306a36Sopenharmony_ci		break;
157362306a36Sopenharmony_ci	case VIRTCHNL_TCP_V6_FLOW:
157462306a36Sopenharmony_ci		dev_info(&adapter->pdev->dev, "dst_mac: %pM src_mac: %pM vlan_id: %hu dst_ip: %pI6 src_ip %pI6 dst_port %hu src_port %hu\n",
157562306a36Sopenharmony_ci			 &f->data.tcp_spec.dst_mac,
157662306a36Sopenharmony_ci			 &f->data.tcp_spec.src_mac,
157762306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.vlan_id),
157862306a36Sopenharmony_ci			 &f->data.tcp_spec.dst_ip,
157962306a36Sopenharmony_ci			 &f->data.tcp_spec.src_ip,
158062306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.dst_port),
158162306a36Sopenharmony_ci			 ntohs(f->data.tcp_spec.src_port));
158262306a36Sopenharmony_ci		break;
158362306a36Sopenharmony_ci	}
158462306a36Sopenharmony_ci}
158562306a36Sopenharmony_ci
158662306a36Sopenharmony_ci/**
158762306a36Sopenharmony_ci * iavf_add_cloud_filter
158862306a36Sopenharmony_ci * @adapter: adapter structure
158962306a36Sopenharmony_ci *
159062306a36Sopenharmony_ci * Request that the PF add cloud filters as specified
159162306a36Sopenharmony_ci * by the user via tc tool.
159262306a36Sopenharmony_ci **/
159362306a36Sopenharmony_civoid iavf_add_cloud_filter(struct iavf_adapter *adapter)
159462306a36Sopenharmony_ci{
159562306a36Sopenharmony_ci	struct iavf_cloud_filter *cf;
159662306a36Sopenharmony_ci	struct virtchnl_filter *f;
159762306a36Sopenharmony_ci	int len = 0, count = 0;
159862306a36Sopenharmony_ci
159962306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
160062306a36Sopenharmony_ci		/* bail because we already have a command pending */
160162306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot add cloud filter, command %d pending\n",
160262306a36Sopenharmony_ci			adapter->current_op);
160362306a36Sopenharmony_ci		return;
160462306a36Sopenharmony_ci	}
160562306a36Sopenharmony_ci	list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
160662306a36Sopenharmony_ci		if (cf->add) {
160762306a36Sopenharmony_ci			count++;
160862306a36Sopenharmony_ci			break;
160962306a36Sopenharmony_ci		}
161062306a36Sopenharmony_ci	}
161162306a36Sopenharmony_ci	if (!count) {
161262306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
161362306a36Sopenharmony_ci		return;
161462306a36Sopenharmony_ci	}
161562306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ADD_CLOUD_FILTER;
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci	len = sizeof(struct virtchnl_filter);
161862306a36Sopenharmony_ci	f = kzalloc(len, GFP_KERNEL);
161962306a36Sopenharmony_ci	if (!f)
162062306a36Sopenharmony_ci		return;
162162306a36Sopenharmony_ci
162262306a36Sopenharmony_ci	list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
162362306a36Sopenharmony_ci		if (cf->add) {
162462306a36Sopenharmony_ci			memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
162562306a36Sopenharmony_ci			cf->add = false;
162662306a36Sopenharmony_ci			cf->state = __IAVF_CF_ADD_PENDING;
162762306a36Sopenharmony_ci			iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_CLOUD_FILTER,
162862306a36Sopenharmony_ci					 (u8 *)f, len);
162962306a36Sopenharmony_ci		}
163062306a36Sopenharmony_ci	}
163162306a36Sopenharmony_ci	kfree(f);
163262306a36Sopenharmony_ci}
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci/**
163562306a36Sopenharmony_ci * iavf_del_cloud_filter
163662306a36Sopenharmony_ci * @adapter: adapter structure
163762306a36Sopenharmony_ci *
163862306a36Sopenharmony_ci * Request that the PF delete cloud filters as specified
163962306a36Sopenharmony_ci * by the user via tc tool.
164062306a36Sopenharmony_ci **/
164162306a36Sopenharmony_civoid iavf_del_cloud_filter(struct iavf_adapter *adapter)
164262306a36Sopenharmony_ci{
164362306a36Sopenharmony_ci	struct iavf_cloud_filter *cf, *cftmp;
164462306a36Sopenharmony_ci	struct virtchnl_filter *f;
164562306a36Sopenharmony_ci	int len = 0, count = 0;
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
164862306a36Sopenharmony_ci		/* bail because we already have a command pending */
164962306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot remove cloud filter, command %d pending\n",
165062306a36Sopenharmony_ci			adapter->current_op);
165162306a36Sopenharmony_ci		return;
165262306a36Sopenharmony_ci	}
165362306a36Sopenharmony_ci	list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
165462306a36Sopenharmony_ci		if (cf->del) {
165562306a36Sopenharmony_ci			count++;
165662306a36Sopenharmony_ci			break;
165762306a36Sopenharmony_ci		}
165862306a36Sopenharmony_ci	}
165962306a36Sopenharmony_ci	if (!count) {
166062306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
166162306a36Sopenharmony_ci		return;
166262306a36Sopenharmony_ci	}
166362306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DEL_CLOUD_FILTER;
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci	len = sizeof(struct virtchnl_filter);
166662306a36Sopenharmony_ci	f = kzalloc(len, GFP_KERNEL);
166762306a36Sopenharmony_ci	if (!f)
166862306a36Sopenharmony_ci		return;
166962306a36Sopenharmony_ci
167062306a36Sopenharmony_ci	list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, list) {
167162306a36Sopenharmony_ci		if (cf->del) {
167262306a36Sopenharmony_ci			memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
167362306a36Sopenharmony_ci			cf->del = false;
167462306a36Sopenharmony_ci			cf->state = __IAVF_CF_DEL_PENDING;
167562306a36Sopenharmony_ci			iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_CLOUD_FILTER,
167662306a36Sopenharmony_ci					 (u8 *)f, len);
167762306a36Sopenharmony_ci		}
167862306a36Sopenharmony_ci	}
167962306a36Sopenharmony_ci	kfree(f);
168062306a36Sopenharmony_ci}
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci/**
168362306a36Sopenharmony_ci * iavf_add_fdir_filter
168462306a36Sopenharmony_ci * @adapter: the VF adapter structure
168562306a36Sopenharmony_ci *
168662306a36Sopenharmony_ci * Request that the PF add Flow Director filters as specified
168762306a36Sopenharmony_ci * by the user via ethtool.
168862306a36Sopenharmony_ci **/
168962306a36Sopenharmony_civoid iavf_add_fdir_filter(struct iavf_adapter *adapter)
169062306a36Sopenharmony_ci{
169162306a36Sopenharmony_ci	struct iavf_fdir_fltr *fdir;
169262306a36Sopenharmony_ci	struct virtchnl_fdir_add *f;
169362306a36Sopenharmony_ci	bool process_fltr = false;
169462306a36Sopenharmony_ci	int len;
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
169762306a36Sopenharmony_ci		/* bail because we already have a command pending */
169862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot add Flow Director filter, command %d pending\n",
169962306a36Sopenharmony_ci			adapter->current_op);
170062306a36Sopenharmony_ci		return;
170162306a36Sopenharmony_ci	}
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	len = sizeof(struct virtchnl_fdir_add);
170462306a36Sopenharmony_ci	f = kzalloc(len, GFP_KERNEL);
170562306a36Sopenharmony_ci	if (!f)
170662306a36Sopenharmony_ci		return;
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci	spin_lock_bh(&adapter->fdir_fltr_lock);
170962306a36Sopenharmony_ci	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
171062306a36Sopenharmony_ci		if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
171162306a36Sopenharmony_ci			process_fltr = true;
171262306a36Sopenharmony_ci			fdir->state = IAVF_FDIR_FLTR_ADD_PENDING;
171362306a36Sopenharmony_ci			memcpy(f, &fdir->vc_add_msg, len);
171462306a36Sopenharmony_ci			break;
171562306a36Sopenharmony_ci		}
171662306a36Sopenharmony_ci	}
171762306a36Sopenharmony_ci	spin_unlock_bh(&adapter->fdir_fltr_lock);
171862306a36Sopenharmony_ci
171962306a36Sopenharmony_ci	if (!process_fltr) {
172062306a36Sopenharmony_ci		/* prevent iavf_add_fdir_filter() from being called when there
172162306a36Sopenharmony_ci		 * are no filters to add
172262306a36Sopenharmony_ci		 */
172362306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_FDIR_FILTER;
172462306a36Sopenharmony_ci		kfree(f);
172562306a36Sopenharmony_ci		return;
172662306a36Sopenharmony_ci	}
172762306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_ADD_FDIR_FILTER;
172862306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_FDIR_FILTER, (u8 *)f, len);
172962306a36Sopenharmony_ci	kfree(f);
173062306a36Sopenharmony_ci}
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci/**
173362306a36Sopenharmony_ci * iavf_del_fdir_filter
173462306a36Sopenharmony_ci * @adapter: the VF adapter structure
173562306a36Sopenharmony_ci *
173662306a36Sopenharmony_ci * Request that the PF delete Flow Director filters as specified
173762306a36Sopenharmony_ci * by the user via ethtool.
173862306a36Sopenharmony_ci **/
173962306a36Sopenharmony_civoid iavf_del_fdir_filter(struct iavf_adapter *adapter)
174062306a36Sopenharmony_ci{
174162306a36Sopenharmony_ci	struct virtchnl_fdir_del f = {};
174262306a36Sopenharmony_ci	struct iavf_fdir_fltr *fdir;
174362306a36Sopenharmony_ci	bool process_fltr = false;
174462306a36Sopenharmony_ci	int len;
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
174762306a36Sopenharmony_ci		/* bail because we already have a command pending */
174862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot remove Flow Director filter, command %d pending\n",
174962306a36Sopenharmony_ci			adapter->current_op);
175062306a36Sopenharmony_ci		return;
175162306a36Sopenharmony_ci	}
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_ci	len = sizeof(struct virtchnl_fdir_del);
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci	spin_lock_bh(&adapter->fdir_fltr_lock);
175662306a36Sopenharmony_ci	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
175762306a36Sopenharmony_ci		if (fdir->state == IAVF_FDIR_FLTR_DEL_REQUEST) {
175862306a36Sopenharmony_ci			process_fltr = true;
175962306a36Sopenharmony_ci			f.vsi_id = fdir->vc_add_msg.vsi_id;
176062306a36Sopenharmony_ci			f.flow_id = fdir->flow_id;
176162306a36Sopenharmony_ci			fdir->state = IAVF_FDIR_FLTR_DEL_PENDING;
176262306a36Sopenharmony_ci			break;
176362306a36Sopenharmony_ci		} else if (fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST) {
176462306a36Sopenharmony_ci			process_fltr = true;
176562306a36Sopenharmony_ci			f.vsi_id = fdir->vc_add_msg.vsi_id;
176662306a36Sopenharmony_ci			f.flow_id = fdir->flow_id;
176762306a36Sopenharmony_ci			fdir->state = IAVF_FDIR_FLTR_DIS_PENDING;
176862306a36Sopenharmony_ci			break;
176962306a36Sopenharmony_ci		}
177062306a36Sopenharmony_ci	}
177162306a36Sopenharmony_ci	spin_unlock_bh(&adapter->fdir_fltr_lock);
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ci	if (!process_fltr) {
177462306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_FDIR_FILTER;
177562306a36Sopenharmony_ci		return;
177662306a36Sopenharmony_ci	}
177762306a36Sopenharmony_ci
177862306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_DEL_FDIR_FILTER;
177962306a36Sopenharmony_ci	iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_FDIR_FILTER, (u8 *)&f, len);
178062306a36Sopenharmony_ci}
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci/**
178362306a36Sopenharmony_ci * iavf_add_adv_rss_cfg
178462306a36Sopenharmony_ci * @adapter: the VF adapter structure
178562306a36Sopenharmony_ci *
178662306a36Sopenharmony_ci * Request that the PF add RSS configuration as specified
178762306a36Sopenharmony_ci * by the user via ethtool.
178862306a36Sopenharmony_ci **/
178962306a36Sopenharmony_civoid iavf_add_adv_rss_cfg(struct iavf_adapter *adapter)
179062306a36Sopenharmony_ci{
179162306a36Sopenharmony_ci	struct virtchnl_rss_cfg *rss_cfg;
179262306a36Sopenharmony_ci	struct iavf_adv_rss *rss;
179362306a36Sopenharmony_ci	bool process_rss = false;
179462306a36Sopenharmony_ci	int len;
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
179762306a36Sopenharmony_ci		/* bail because we already have a command pending */
179862306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot add RSS configuration, command %d pending\n",
179962306a36Sopenharmony_ci			adapter->current_op);
180062306a36Sopenharmony_ci		return;
180162306a36Sopenharmony_ci	}
180262306a36Sopenharmony_ci
180362306a36Sopenharmony_ci	len = sizeof(struct virtchnl_rss_cfg);
180462306a36Sopenharmony_ci	rss_cfg = kzalloc(len, GFP_KERNEL);
180562306a36Sopenharmony_ci	if (!rss_cfg)
180662306a36Sopenharmony_ci		return;
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci	spin_lock_bh(&adapter->adv_rss_lock);
180962306a36Sopenharmony_ci	list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
181062306a36Sopenharmony_ci		if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
181162306a36Sopenharmony_ci			process_rss = true;
181262306a36Sopenharmony_ci			rss->state = IAVF_ADV_RSS_ADD_PENDING;
181362306a36Sopenharmony_ci			memcpy(rss_cfg, &rss->cfg_msg, len);
181462306a36Sopenharmony_ci			iavf_print_adv_rss_cfg(adapter, rss,
181562306a36Sopenharmony_ci					       "Input set change for",
181662306a36Sopenharmony_ci					       "is pending");
181762306a36Sopenharmony_ci			break;
181862306a36Sopenharmony_ci		}
181962306a36Sopenharmony_ci	}
182062306a36Sopenharmony_ci	spin_unlock_bh(&adapter->adv_rss_lock);
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci	if (process_rss) {
182362306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_ADD_RSS_CFG;
182462306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_RSS_CFG,
182562306a36Sopenharmony_ci				 (u8 *)rss_cfg, len);
182662306a36Sopenharmony_ci	} else {
182762306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_ADV_RSS_CFG;
182862306a36Sopenharmony_ci	}
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci	kfree(rss_cfg);
183162306a36Sopenharmony_ci}
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci/**
183462306a36Sopenharmony_ci * iavf_del_adv_rss_cfg
183562306a36Sopenharmony_ci * @adapter: the VF adapter structure
183662306a36Sopenharmony_ci *
183762306a36Sopenharmony_ci * Request that the PF delete RSS configuration as specified
183862306a36Sopenharmony_ci * by the user via ethtool.
183962306a36Sopenharmony_ci **/
184062306a36Sopenharmony_civoid iavf_del_adv_rss_cfg(struct iavf_adapter *adapter)
184162306a36Sopenharmony_ci{
184262306a36Sopenharmony_ci	struct virtchnl_rss_cfg *rss_cfg;
184362306a36Sopenharmony_ci	struct iavf_adv_rss *rss;
184462306a36Sopenharmony_ci	bool process_rss = false;
184562306a36Sopenharmony_ci	int len;
184662306a36Sopenharmony_ci
184762306a36Sopenharmony_ci	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
184862306a36Sopenharmony_ci		/* bail because we already have a command pending */
184962306a36Sopenharmony_ci		dev_err(&adapter->pdev->dev, "Cannot remove RSS configuration, command %d pending\n",
185062306a36Sopenharmony_ci			adapter->current_op);
185162306a36Sopenharmony_ci		return;
185262306a36Sopenharmony_ci	}
185362306a36Sopenharmony_ci
185462306a36Sopenharmony_ci	len = sizeof(struct virtchnl_rss_cfg);
185562306a36Sopenharmony_ci	rss_cfg = kzalloc(len, GFP_KERNEL);
185662306a36Sopenharmony_ci	if (!rss_cfg)
185762306a36Sopenharmony_ci		return;
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	spin_lock_bh(&adapter->adv_rss_lock);
186062306a36Sopenharmony_ci	list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
186162306a36Sopenharmony_ci		if (rss->state == IAVF_ADV_RSS_DEL_REQUEST) {
186262306a36Sopenharmony_ci			process_rss = true;
186362306a36Sopenharmony_ci			rss->state = IAVF_ADV_RSS_DEL_PENDING;
186462306a36Sopenharmony_ci			memcpy(rss_cfg, &rss->cfg_msg, len);
186562306a36Sopenharmony_ci			break;
186662306a36Sopenharmony_ci		}
186762306a36Sopenharmony_ci	}
186862306a36Sopenharmony_ci	spin_unlock_bh(&adapter->adv_rss_lock);
186962306a36Sopenharmony_ci
187062306a36Sopenharmony_ci	if (process_rss) {
187162306a36Sopenharmony_ci		adapter->current_op = VIRTCHNL_OP_DEL_RSS_CFG;
187262306a36Sopenharmony_ci		iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_RSS_CFG,
187362306a36Sopenharmony_ci				 (u8 *)rss_cfg, len);
187462306a36Sopenharmony_ci	} else {
187562306a36Sopenharmony_ci		adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
187662306a36Sopenharmony_ci	}
187762306a36Sopenharmony_ci
187862306a36Sopenharmony_ci	kfree(rss_cfg);
187962306a36Sopenharmony_ci}
188062306a36Sopenharmony_ci
188162306a36Sopenharmony_ci/**
188262306a36Sopenharmony_ci * iavf_request_reset
188362306a36Sopenharmony_ci * @adapter: adapter structure
188462306a36Sopenharmony_ci *
188562306a36Sopenharmony_ci * Request that the PF reset this VF. No response is expected.
188662306a36Sopenharmony_ci **/
188762306a36Sopenharmony_ciint iavf_request_reset(struct iavf_adapter *adapter)
188862306a36Sopenharmony_ci{
188962306a36Sopenharmony_ci	int err;
189062306a36Sopenharmony_ci	/* Don't check CURRENT_OP - this is always higher priority */
189162306a36Sopenharmony_ci	err = iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
189262306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_UNKNOWN;
189362306a36Sopenharmony_ci	return err;
189462306a36Sopenharmony_ci}
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_ci/**
189762306a36Sopenharmony_ci * iavf_netdev_features_vlan_strip_set - update vlan strip status
189862306a36Sopenharmony_ci * @netdev: ptr to netdev being adjusted
189962306a36Sopenharmony_ci * @enable: enable or disable vlan strip
190062306a36Sopenharmony_ci *
190162306a36Sopenharmony_ci * Helper function to change vlan strip status in netdev->features.
190262306a36Sopenharmony_ci */
190362306a36Sopenharmony_cistatic void iavf_netdev_features_vlan_strip_set(struct net_device *netdev,
190462306a36Sopenharmony_ci						const bool enable)
190562306a36Sopenharmony_ci{
190662306a36Sopenharmony_ci	if (enable)
190762306a36Sopenharmony_ci		netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
190862306a36Sopenharmony_ci	else
190962306a36Sopenharmony_ci		netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
191062306a36Sopenharmony_ci}
191162306a36Sopenharmony_ci
191262306a36Sopenharmony_ci/**
191362306a36Sopenharmony_ci * iavf_activate_fdir_filters - Reactivate all FDIR filters after a reset
191462306a36Sopenharmony_ci * @adapter: private adapter structure
191562306a36Sopenharmony_ci *
191662306a36Sopenharmony_ci * Called after a reset to re-add all FDIR filters and delete some of them
191762306a36Sopenharmony_ci * if they were pending to be deleted.
191862306a36Sopenharmony_ci */
191962306a36Sopenharmony_cistatic void iavf_activate_fdir_filters(struct iavf_adapter *adapter)
192062306a36Sopenharmony_ci{
192162306a36Sopenharmony_ci	struct iavf_fdir_fltr *f, *ftmp;
192262306a36Sopenharmony_ci	bool add_filters = false;
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci	spin_lock_bh(&adapter->fdir_fltr_lock);
192562306a36Sopenharmony_ci	list_for_each_entry_safe(f, ftmp, &adapter->fdir_list_head, list) {
192662306a36Sopenharmony_ci		if (f->state == IAVF_FDIR_FLTR_ADD_REQUEST ||
192762306a36Sopenharmony_ci		    f->state == IAVF_FDIR_FLTR_ADD_PENDING ||
192862306a36Sopenharmony_ci		    f->state == IAVF_FDIR_FLTR_ACTIVE) {
192962306a36Sopenharmony_ci			/* All filters and requests have been removed in PF,
193062306a36Sopenharmony_ci			 * restore them
193162306a36Sopenharmony_ci			 */
193262306a36Sopenharmony_ci			f->state = IAVF_FDIR_FLTR_ADD_REQUEST;
193362306a36Sopenharmony_ci			add_filters = true;
193462306a36Sopenharmony_ci		} else if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST ||
193562306a36Sopenharmony_ci			   f->state == IAVF_FDIR_FLTR_DIS_PENDING) {
193662306a36Sopenharmony_ci			/* Link down state, leave filters as inactive */
193762306a36Sopenharmony_ci			f->state = IAVF_FDIR_FLTR_INACTIVE;
193862306a36Sopenharmony_ci		} else if (f->state == IAVF_FDIR_FLTR_DEL_REQUEST ||
193962306a36Sopenharmony_ci			   f->state == IAVF_FDIR_FLTR_DEL_PENDING) {
194062306a36Sopenharmony_ci			/* Delete filters that were pending to be deleted, the
194162306a36Sopenharmony_ci			 * list on PF is already cleared after a reset
194262306a36Sopenharmony_ci			 */
194362306a36Sopenharmony_ci			list_del(&f->list);
194462306a36Sopenharmony_ci			kfree(f);
194562306a36Sopenharmony_ci			adapter->fdir_active_fltr--;
194662306a36Sopenharmony_ci		}
194762306a36Sopenharmony_ci	}
194862306a36Sopenharmony_ci	spin_unlock_bh(&adapter->fdir_fltr_lock);
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci	if (add_filters)
195162306a36Sopenharmony_ci		adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER;
195262306a36Sopenharmony_ci}
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_ci/**
195562306a36Sopenharmony_ci * iavf_virtchnl_completion
195662306a36Sopenharmony_ci * @adapter: adapter structure
195762306a36Sopenharmony_ci * @v_opcode: opcode sent by PF
195862306a36Sopenharmony_ci * @v_retval: retval sent by PF
195962306a36Sopenharmony_ci * @msg: message sent by PF
196062306a36Sopenharmony_ci * @msglen: message length
196162306a36Sopenharmony_ci *
196262306a36Sopenharmony_ci * Asynchronous completion function for admin queue messages. Rather than busy
196362306a36Sopenharmony_ci * wait, we fire off our requests and assume that no errors will be returned.
196462306a36Sopenharmony_ci * This function handles the reply messages.
196562306a36Sopenharmony_ci **/
196662306a36Sopenharmony_civoid iavf_virtchnl_completion(struct iavf_adapter *adapter,
196762306a36Sopenharmony_ci			      enum virtchnl_ops v_opcode,
196862306a36Sopenharmony_ci			      enum iavf_status v_retval, u8 *msg, u16 msglen)
196962306a36Sopenharmony_ci{
197062306a36Sopenharmony_ci	struct net_device *netdev = adapter->netdev;
197162306a36Sopenharmony_ci
197262306a36Sopenharmony_ci	if (v_opcode == VIRTCHNL_OP_EVENT) {
197362306a36Sopenharmony_ci		struct virtchnl_pf_event *vpe =
197462306a36Sopenharmony_ci			(struct virtchnl_pf_event *)msg;
197562306a36Sopenharmony_ci		bool link_up = iavf_get_vpe_link_status(adapter, vpe);
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci		switch (vpe->event) {
197862306a36Sopenharmony_ci		case VIRTCHNL_EVENT_LINK_CHANGE:
197962306a36Sopenharmony_ci			iavf_set_adapter_link_speed_from_vpe(adapter, vpe);
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci			/* we've already got the right link status, bail */
198262306a36Sopenharmony_ci			if (adapter->link_up == link_up)
198362306a36Sopenharmony_ci				break;
198462306a36Sopenharmony_ci
198562306a36Sopenharmony_ci			if (link_up) {
198662306a36Sopenharmony_ci				/* If we get link up message and start queues
198762306a36Sopenharmony_ci				 * before our queues are configured it will
198862306a36Sopenharmony_ci				 * trigger a TX hang. In that case, just ignore
198962306a36Sopenharmony_ci				 * the link status message,we'll get another one
199062306a36Sopenharmony_ci				 * after we enable queues and actually prepared
199162306a36Sopenharmony_ci				 * to send traffic.
199262306a36Sopenharmony_ci				 */
199362306a36Sopenharmony_ci				if (adapter->state != __IAVF_RUNNING)
199462306a36Sopenharmony_ci					break;
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_ci				/* For ADq enabled VF, we reconfigure VSIs and
199762306a36Sopenharmony_ci				 * re-allocate queues. Hence wait till all
199862306a36Sopenharmony_ci				 * queues are enabled.
199962306a36Sopenharmony_ci				 */
200062306a36Sopenharmony_ci				if (adapter->flags &
200162306a36Sopenharmony_ci				    IAVF_FLAG_QUEUES_DISABLED)
200262306a36Sopenharmony_ci					break;
200362306a36Sopenharmony_ci			}
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci			adapter->link_up = link_up;
200662306a36Sopenharmony_ci			if (link_up) {
200762306a36Sopenharmony_ci				netif_tx_start_all_queues(netdev);
200862306a36Sopenharmony_ci				netif_carrier_on(netdev);
200962306a36Sopenharmony_ci			} else {
201062306a36Sopenharmony_ci				netif_tx_stop_all_queues(netdev);
201162306a36Sopenharmony_ci				netif_carrier_off(netdev);
201262306a36Sopenharmony_ci			}
201362306a36Sopenharmony_ci			iavf_print_link_message(adapter);
201462306a36Sopenharmony_ci			break;
201562306a36Sopenharmony_ci		case VIRTCHNL_EVENT_RESET_IMPENDING:
201662306a36Sopenharmony_ci			dev_info(&adapter->pdev->dev, "Reset indication received from the PF\n");
201762306a36Sopenharmony_ci			if (!(adapter->flags & IAVF_FLAG_RESET_PENDING)) {
201862306a36Sopenharmony_ci				dev_info(&adapter->pdev->dev, "Scheduling reset task\n");
201962306a36Sopenharmony_ci				iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING);
202062306a36Sopenharmony_ci			}
202162306a36Sopenharmony_ci			break;
202262306a36Sopenharmony_ci		default:
202362306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Unknown event %d from PF\n",
202462306a36Sopenharmony_ci				vpe->event);
202562306a36Sopenharmony_ci			break;
202662306a36Sopenharmony_ci		}
202762306a36Sopenharmony_ci		return;
202862306a36Sopenharmony_ci	}
202962306a36Sopenharmony_ci	if (v_retval) {
203062306a36Sopenharmony_ci		switch (v_opcode) {
203162306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_VLAN:
203262306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
203362306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
203462306a36Sopenharmony_ci			break;
203562306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_ETH_ADDR:
203662306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n",
203762306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
203862306a36Sopenharmony_ci			iavf_mac_add_reject(adapter);
203962306a36Sopenharmony_ci			/* restore administratively set MAC address */
204062306a36Sopenharmony_ci			ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
204162306a36Sopenharmony_ci			wake_up(&adapter->vc_waitqueue);
204262306a36Sopenharmony_ci			break;
204362306a36Sopenharmony_ci		case VIRTCHNL_OP_DEL_VLAN:
204462306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n",
204562306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
204662306a36Sopenharmony_ci			break;
204762306a36Sopenharmony_ci		case VIRTCHNL_OP_DEL_ETH_ADDR:
204862306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
204962306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
205062306a36Sopenharmony_ci			break;
205162306a36Sopenharmony_ci		case VIRTCHNL_OP_ENABLE_CHANNELS:
205262306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to configure queue channels, error %s\n",
205362306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
205462306a36Sopenharmony_ci			adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
205562306a36Sopenharmony_ci			adapter->ch_config.state = __IAVF_TC_INVALID;
205662306a36Sopenharmony_ci			netdev_reset_tc(netdev);
205762306a36Sopenharmony_ci			netif_tx_start_all_queues(netdev);
205862306a36Sopenharmony_ci			break;
205962306a36Sopenharmony_ci		case VIRTCHNL_OP_DISABLE_CHANNELS:
206062306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "Failed to disable queue channels, error %s\n",
206162306a36Sopenharmony_ci				iavf_stat_str(&adapter->hw, v_retval));
206262306a36Sopenharmony_ci			adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
206362306a36Sopenharmony_ci			adapter->ch_config.state = __IAVF_TC_RUNNING;
206462306a36Sopenharmony_ci			netif_tx_start_all_queues(netdev);
206562306a36Sopenharmony_ci			break;
206662306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
206762306a36Sopenharmony_ci			struct iavf_cloud_filter *cf, *cftmp;
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci			list_for_each_entry_safe(cf, cftmp,
207062306a36Sopenharmony_ci						 &adapter->cloud_filter_list,
207162306a36Sopenharmony_ci						 list) {
207262306a36Sopenharmony_ci				if (cf->state == __IAVF_CF_ADD_PENDING) {
207362306a36Sopenharmony_ci					cf->state = __IAVF_CF_INVALID;
207462306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to add cloud filter, error %s\n",
207562306a36Sopenharmony_ci						 iavf_stat_str(&adapter->hw,
207662306a36Sopenharmony_ci							       v_retval));
207762306a36Sopenharmony_ci					iavf_print_cloud_filter(adapter,
207862306a36Sopenharmony_ci								&cf->f);
207962306a36Sopenharmony_ci					list_del(&cf->list);
208062306a36Sopenharmony_ci					kfree(cf);
208162306a36Sopenharmony_ci					adapter->num_cloud_filters--;
208262306a36Sopenharmony_ci				}
208362306a36Sopenharmony_ci			}
208462306a36Sopenharmony_ci			}
208562306a36Sopenharmony_ci			break;
208662306a36Sopenharmony_ci		case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
208762306a36Sopenharmony_ci			struct iavf_cloud_filter *cf;
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci			list_for_each_entry(cf, &adapter->cloud_filter_list,
209062306a36Sopenharmony_ci					    list) {
209162306a36Sopenharmony_ci				if (cf->state == __IAVF_CF_DEL_PENDING) {
209262306a36Sopenharmony_ci					cf->state = __IAVF_CF_ACTIVE;
209362306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to del cloud filter, error %s\n",
209462306a36Sopenharmony_ci						 iavf_stat_str(&adapter->hw,
209562306a36Sopenharmony_ci							       v_retval));
209662306a36Sopenharmony_ci					iavf_print_cloud_filter(adapter,
209762306a36Sopenharmony_ci								&cf->f);
209862306a36Sopenharmony_ci				}
209962306a36Sopenharmony_ci			}
210062306a36Sopenharmony_ci			}
210162306a36Sopenharmony_ci			break;
210262306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_FDIR_FILTER: {
210362306a36Sopenharmony_ci			struct iavf_fdir_fltr *fdir, *fdir_tmp;
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_ci			spin_lock_bh(&adapter->fdir_fltr_lock);
210662306a36Sopenharmony_ci			list_for_each_entry_safe(fdir, fdir_tmp,
210762306a36Sopenharmony_ci						 &adapter->fdir_list_head,
210862306a36Sopenharmony_ci						 list) {
210962306a36Sopenharmony_ci				if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING) {
211062306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to add Flow Director filter, error %s\n",
211162306a36Sopenharmony_ci						 iavf_stat_str(&adapter->hw,
211262306a36Sopenharmony_ci							       v_retval));
211362306a36Sopenharmony_ci					iavf_print_fdir_fltr(adapter, fdir);
211462306a36Sopenharmony_ci					if (msglen)
211562306a36Sopenharmony_ci						dev_err(&adapter->pdev->dev,
211662306a36Sopenharmony_ci							"%s\n", msg);
211762306a36Sopenharmony_ci					list_del(&fdir->list);
211862306a36Sopenharmony_ci					kfree(fdir);
211962306a36Sopenharmony_ci					adapter->fdir_active_fltr--;
212062306a36Sopenharmony_ci				}
212162306a36Sopenharmony_ci			}
212262306a36Sopenharmony_ci			spin_unlock_bh(&adapter->fdir_fltr_lock);
212362306a36Sopenharmony_ci			}
212462306a36Sopenharmony_ci			break;
212562306a36Sopenharmony_ci		case VIRTCHNL_OP_DEL_FDIR_FILTER: {
212662306a36Sopenharmony_ci			struct iavf_fdir_fltr *fdir;
212762306a36Sopenharmony_ci
212862306a36Sopenharmony_ci			spin_lock_bh(&adapter->fdir_fltr_lock);
212962306a36Sopenharmony_ci			list_for_each_entry(fdir, &adapter->fdir_list_head,
213062306a36Sopenharmony_ci					    list) {
213162306a36Sopenharmony_ci				if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING ||
213262306a36Sopenharmony_ci				    fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) {
213362306a36Sopenharmony_ci					fdir->state = IAVF_FDIR_FLTR_ACTIVE;
213462306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to del Flow Director filter, error %s\n",
213562306a36Sopenharmony_ci						 iavf_stat_str(&adapter->hw,
213662306a36Sopenharmony_ci							       v_retval));
213762306a36Sopenharmony_ci					iavf_print_fdir_fltr(adapter, fdir);
213862306a36Sopenharmony_ci				}
213962306a36Sopenharmony_ci			}
214062306a36Sopenharmony_ci			spin_unlock_bh(&adapter->fdir_fltr_lock);
214162306a36Sopenharmony_ci			}
214262306a36Sopenharmony_ci			break;
214362306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_RSS_CFG: {
214462306a36Sopenharmony_ci			struct iavf_adv_rss *rss, *rss_tmp;
214562306a36Sopenharmony_ci
214662306a36Sopenharmony_ci			spin_lock_bh(&adapter->adv_rss_lock);
214762306a36Sopenharmony_ci			list_for_each_entry_safe(rss, rss_tmp,
214862306a36Sopenharmony_ci						 &adapter->adv_rss_list_head,
214962306a36Sopenharmony_ci						 list) {
215062306a36Sopenharmony_ci				if (rss->state == IAVF_ADV_RSS_ADD_PENDING) {
215162306a36Sopenharmony_ci					iavf_print_adv_rss_cfg(adapter, rss,
215262306a36Sopenharmony_ci							       "Failed to change the input set for",
215362306a36Sopenharmony_ci							       NULL);
215462306a36Sopenharmony_ci					list_del(&rss->list);
215562306a36Sopenharmony_ci					kfree(rss);
215662306a36Sopenharmony_ci				}
215762306a36Sopenharmony_ci			}
215862306a36Sopenharmony_ci			spin_unlock_bh(&adapter->adv_rss_lock);
215962306a36Sopenharmony_ci			}
216062306a36Sopenharmony_ci			break;
216162306a36Sopenharmony_ci		case VIRTCHNL_OP_DEL_RSS_CFG: {
216262306a36Sopenharmony_ci			struct iavf_adv_rss *rss;
216362306a36Sopenharmony_ci
216462306a36Sopenharmony_ci			spin_lock_bh(&adapter->adv_rss_lock);
216562306a36Sopenharmony_ci			list_for_each_entry(rss, &adapter->adv_rss_list_head,
216662306a36Sopenharmony_ci					    list) {
216762306a36Sopenharmony_ci				if (rss->state == IAVF_ADV_RSS_DEL_PENDING) {
216862306a36Sopenharmony_ci					rss->state = IAVF_ADV_RSS_ACTIVE;
216962306a36Sopenharmony_ci					dev_err(&adapter->pdev->dev, "Failed to delete RSS configuration, error %s\n",
217062306a36Sopenharmony_ci						iavf_stat_str(&adapter->hw,
217162306a36Sopenharmony_ci							      v_retval));
217262306a36Sopenharmony_ci				}
217362306a36Sopenharmony_ci			}
217462306a36Sopenharmony_ci			spin_unlock_bh(&adapter->adv_rss_lock);
217562306a36Sopenharmony_ci			}
217662306a36Sopenharmony_ci			break;
217762306a36Sopenharmony_ci		case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
217862306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
217962306a36Sopenharmony_ci			/* Vlan stripping could not be enabled by ethtool.
218062306a36Sopenharmony_ci			 * Disable it in netdev->features.
218162306a36Sopenharmony_ci			 */
218262306a36Sopenharmony_ci			iavf_netdev_features_vlan_strip_set(netdev, false);
218362306a36Sopenharmony_ci			break;
218462306a36Sopenharmony_ci		case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
218562306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
218662306a36Sopenharmony_ci			/* Vlan stripping could not be disabled by ethtool.
218762306a36Sopenharmony_ci			 * Enable it in netdev->features.
218862306a36Sopenharmony_ci			 */
218962306a36Sopenharmony_ci			iavf_netdev_features_vlan_strip_set(netdev, true);
219062306a36Sopenharmony_ci			break;
219162306a36Sopenharmony_ci		case VIRTCHNL_OP_ADD_VLAN_V2:
219262306a36Sopenharmony_ci			iavf_vlan_add_reject(adapter);
219362306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
219462306a36Sopenharmony_ci				 iavf_stat_str(&adapter->hw, v_retval));
219562306a36Sopenharmony_ci			break;
219662306a36Sopenharmony_ci		default:
219762306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
219862306a36Sopenharmony_ci				v_retval, iavf_stat_str(&adapter->hw, v_retval),
219962306a36Sopenharmony_ci				v_opcode);
220062306a36Sopenharmony_ci		}
220162306a36Sopenharmony_ci	}
220262306a36Sopenharmony_ci	switch (v_opcode) {
220362306a36Sopenharmony_ci	case VIRTCHNL_OP_ADD_ETH_ADDR:
220462306a36Sopenharmony_ci		if (!v_retval)
220562306a36Sopenharmony_ci			iavf_mac_add_ok(adapter);
220662306a36Sopenharmony_ci		if (!ether_addr_equal(netdev->dev_addr, adapter->hw.mac.addr))
220762306a36Sopenharmony_ci			if (!ether_addr_equal(netdev->dev_addr,
220862306a36Sopenharmony_ci					      adapter->hw.mac.addr)) {
220962306a36Sopenharmony_ci				netif_addr_lock_bh(netdev);
221062306a36Sopenharmony_ci				eth_hw_addr_set(netdev, adapter->hw.mac.addr);
221162306a36Sopenharmony_ci				netif_addr_unlock_bh(netdev);
221262306a36Sopenharmony_ci			}
221362306a36Sopenharmony_ci		wake_up(&adapter->vc_waitqueue);
221462306a36Sopenharmony_ci		break;
221562306a36Sopenharmony_ci	case VIRTCHNL_OP_GET_STATS: {
221662306a36Sopenharmony_ci		struct iavf_eth_stats *stats =
221762306a36Sopenharmony_ci			(struct iavf_eth_stats *)msg;
221862306a36Sopenharmony_ci		netdev->stats.rx_packets = stats->rx_unicast +
221962306a36Sopenharmony_ci					   stats->rx_multicast +
222062306a36Sopenharmony_ci					   stats->rx_broadcast;
222162306a36Sopenharmony_ci		netdev->stats.tx_packets = stats->tx_unicast +
222262306a36Sopenharmony_ci					   stats->tx_multicast +
222362306a36Sopenharmony_ci					   stats->tx_broadcast;
222462306a36Sopenharmony_ci		netdev->stats.rx_bytes = stats->rx_bytes;
222562306a36Sopenharmony_ci		netdev->stats.tx_bytes = stats->tx_bytes;
222662306a36Sopenharmony_ci		netdev->stats.tx_errors = stats->tx_errors;
222762306a36Sopenharmony_ci		netdev->stats.rx_dropped = stats->rx_discards;
222862306a36Sopenharmony_ci		netdev->stats.tx_dropped = stats->tx_discards;
222962306a36Sopenharmony_ci		adapter->current_stats = *stats;
223062306a36Sopenharmony_ci		}
223162306a36Sopenharmony_ci		break;
223262306a36Sopenharmony_ci	case VIRTCHNL_OP_GET_VF_RESOURCES: {
223362306a36Sopenharmony_ci		u16 len = IAVF_VIRTCHNL_VF_RESOURCE_SIZE;
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci		memcpy(adapter->vf_res, msg, min(msglen, len));
223662306a36Sopenharmony_ci		iavf_validate_num_queues(adapter);
223762306a36Sopenharmony_ci		iavf_vf_parse_hw_config(&adapter->hw, adapter->vf_res);
223862306a36Sopenharmony_ci		if (is_zero_ether_addr(adapter->hw.mac.addr)) {
223962306a36Sopenharmony_ci			/* restore current mac address */
224062306a36Sopenharmony_ci			ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
224162306a36Sopenharmony_ci		} else {
224262306a36Sopenharmony_ci			netif_addr_lock_bh(netdev);
224362306a36Sopenharmony_ci			/* refresh current mac address if changed */
224462306a36Sopenharmony_ci			ether_addr_copy(netdev->perm_addr,
224562306a36Sopenharmony_ci					adapter->hw.mac.addr);
224662306a36Sopenharmony_ci			netif_addr_unlock_bh(netdev);
224762306a36Sopenharmony_ci		}
224862306a36Sopenharmony_ci		spin_lock_bh(&adapter->mac_vlan_list_lock);
224962306a36Sopenharmony_ci		iavf_add_filter(adapter, adapter->hw.mac.addr);
225062306a36Sopenharmony_ci
225162306a36Sopenharmony_ci		if (VLAN_ALLOWED(adapter)) {
225262306a36Sopenharmony_ci			if (!list_empty(&adapter->vlan_filter_list)) {
225362306a36Sopenharmony_ci				struct iavf_vlan_filter *vlf;
225462306a36Sopenharmony_ci
225562306a36Sopenharmony_ci				/* re-add all VLAN filters over virtchnl */
225662306a36Sopenharmony_ci				list_for_each_entry(vlf,
225762306a36Sopenharmony_ci						    &adapter->vlan_filter_list,
225862306a36Sopenharmony_ci						    list)
225962306a36Sopenharmony_ci					vlf->state = IAVF_VLAN_ADD;
226062306a36Sopenharmony_ci
226162306a36Sopenharmony_ci				adapter->aq_required |=
226262306a36Sopenharmony_ci					IAVF_FLAG_AQ_ADD_VLAN_FILTER;
226362306a36Sopenharmony_ci			}
226462306a36Sopenharmony_ci		}
226562306a36Sopenharmony_ci
226662306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
226762306a36Sopenharmony_ci
226862306a36Sopenharmony_ci		iavf_activate_fdir_filters(adapter);
226962306a36Sopenharmony_ci
227062306a36Sopenharmony_ci		iavf_parse_vf_resource_msg(adapter);
227162306a36Sopenharmony_ci
227262306a36Sopenharmony_ci		/* negotiated VIRTCHNL_VF_OFFLOAD_VLAN_V2, so wait for the
227362306a36Sopenharmony_ci		 * response to VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS to finish
227462306a36Sopenharmony_ci		 * configuration
227562306a36Sopenharmony_ci		 */
227662306a36Sopenharmony_ci		if (VLAN_V2_ALLOWED(adapter))
227762306a36Sopenharmony_ci			break;
227862306a36Sopenharmony_ci		/* fallthrough and finish config if VIRTCHNL_VF_OFFLOAD_VLAN_V2
227962306a36Sopenharmony_ci		 * wasn't successfully negotiated with the PF
228062306a36Sopenharmony_ci		 */
228162306a36Sopenharmony_ci		}
228262306a36Sopenharmony_ci		fallthrough;
228362306a36Sopenharmony_ci	case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS: {
228462306a36Sopenharmony_ci		struct iavf_mac_filter *f;
228562306a36Sopenharmony_ci		bool was_mac_changed;
228662306a36Sopenharmony_ci		u64 aq_required = 0;
228762306a36Sopenharmony_ci
228862306a36Sopenharmony_ci		if (v_opcode == VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS)
228962306a36Sopenharmony_ci			memcpy(&adapter->vlan_v2_caps, msg,
229062306a36Sopenharmony_ci			       min_t(u16, msglen,
229162306a36Sopenharmony_ci				     sizeof(adapter->vlan_v2_caps)));
229262306a36Sopenharmony_ci
229362306a36Sopenharmony_ci		iavf_process_config(adapter);
229462306a36Sopenharmony_ci		adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES;
229562306a36Sopenharmony_ci		iavf_schedule_finish_config(adapter);
229662306a36Sopenharmony_ci
229762306a36Sopenharmony_ci		iavf_set_queue_vlan_tag_loc(adapter);
229862306a36Sopenharmony_ci
229962306a36Sopenharmony_ci		was_mac_changed = !ether_addr_equal(netdev->dev_addr,
230062306a36Sopenharmony_ci						    adapter->hw.mac.addr);
230162306a36Sopenharmony_ci
230262306a36Sopenharmony_ci		spin_lock_bh(&adapter->mac_vlan_list_lock);
230362306a36Sopenharmony_ci
230462306a36Sopenharmony_ci		/* re-add all MAC filters */
230562306a36Sopenharmony_ci		list_for_each_entry(f, &adapter->mac_filter_list, list) {
230662306a36Sopenharmony_ci			if (was_mac_changed &&
230762306a36Sopenharmony_ci			    ether_addr_equal(netdev->dev_addr, f->macaddr))
230862306a36Sopenharmony_ci				ether_addr_copy(f->macaddr,
230962306a36Sopenharmony_ci						adapter->hw.mac.addr);
231062306a36Sopenharmony_ci
231162306a36Sopenharmony_ci			f->is_new_mac = true;
231262306a36Sopenharmony_ci			f->add = true;
231362306a36Sopenharmony_ci			f->add_handled = false;
231462306a36Sopenharmony_ci			f->remove = false;
231562306a36Sopenharmony_ci		}
231662306a36Sopenharmony_ci
231762306a36Sopenharmony_ci		/* re-add all VLAN filters */
231862306a36Sopenharmony_ci		if (VLAN_FILTERING_ALLOWED(adapter)) {
231962306a36Sopenharmony_ci			struct iavf_vlan_filter *vlf;
232062306a36Sopenharmony_ci
232162306a36Sopenharmony_ci			if (!list_empty(&adapter->vlan_filter_list)) {
232262306a36Sopenharmony_ci				list_for_each_entry(vlf,
232362306a36Sopenharmony_ci						    &adapter->vlan_filter_list,
232462306a36Sopenharmony_ci						    list)
232562306a36Sopenharmony_ci					vlf->state = IAVF_VLAN_ADD;
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci				aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
232862306a36Sopenharmony_ci			}
232962306a36Sopenharmony_ci		}
233062306a36Sopenharmony_ci
233162306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
233262306a36Sopenharmony_ci
233362306a36Sopenharmony_ci		netif_addr_lock_bh(netdev);
233462306a36Sopenharmony_ci		eth_hw_addr_set(netdev, adapter->hw.mac.addr);
233562306a36Sopenharmony_ci		netif_addr_unlock_bh(netdev);
233662306a36Sopenharmony_ci
233762306a36Sopenharmony_ci		adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER |
233862306a36Sopenharmony_ci			aq_required;
233962306a36Sopenharmony_ci		}
234062306a36Sopenharmony_ci		break;
234162306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_QUEUES:
234262306a36Sopenharmony_ci		/* enable transmits */
234362306a36Sopenharmony_ci		iavf_irq_enable(adapter, true);
234462306a36Sopenharmony_ci		wake_up(&adapter->reset_waitqueue);
234562306a36Sopenharmony_ci		adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED;
234662306a36Sopenharmony_ci		break;
234762306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_QUEUES:
234862306a36Sopenharmony_ci		iavf_free_all_tx_resources(adapter);
234962306a36Sopenharmony_ci		iavf_free_all_rx_resources(adapter);
235062306a36Sopenharmony_ci		if (adapter->state == __IAVF_DOWN_PENDING) {
235162306a36Sopenharmony_ci			iavf_change_state(adapter, __IAVF_DOWN);
235262306a36Sopenharmony_ci			wake_up(&adapter->down_waitqueue);
235362306a36Sopenharmony_ci		}
235462306a36Sopenharmony_ci		break;
235562306a36Sopenharmony_ci	case VIRTCHNL_OP_VERSION:
235662306a36Sopenharmony_ci	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
235762306a36Sopenharmony_ci		/* Don't display an error if we get these out of sequence.
235862306a36Sopenharmony_ci		 * If the firmware needed to get kicked, we'll get these and
235962306a36Sopenharmony_ci		 * it's no problem.
236062306a36Sopenharmony_ci		 */
236162306a36Sopenharmony_ci		if (v_opcode != adapter->current_op)
236262306a36Sopenharmony_ci			return;
236362306a36Sopenharmony_ci		break;
236462306a36Sopenharmony_ci	case VIRTCHNL_OP_RDMA:
236562306a36Sopenharmony_ci		/* Gobble zero-length replies from the PF. They indicate that
236662306a36Sopenharmony_ci		 * a previous message was received OK, and the client doesn't
236762306a36Sopenharmony_ci		 * care about that.
236862306a36Sopenharmony_ci		 */
236962306a36Sopenharmony_ci		if (msglen && CLIENT_ENABLED(adapter))
237062306a36Sopenharmony_ci			iavf_notify_client_message(&adapter->vsi, msg, msglen);
237162306a36Sopenharmony_ci		break;
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ci	case VIRTCHNL_OP_CONFIG_RDMA_IRQ_MAP:
237462306a36Sopenharmony_ci		adapter->client_pending &=
237562306a36Sopenharmony_ci				~(BIT(VIRTCHNL_OP_CONFIG_RDMA_IRQ_MAP));
237662306a36Sopenharmony_ci		break;
237762306a36Sopenharmony_ci	case VIRTCHNL_OP_GET_RSS_HENA_CAPS: {
237862306a36Sopenharmony_ci		struct virtchnl_rss_hena *vrh = (struct virtchnl_rss_hena *)msg;
237962306a36Sopenharmony_ci
238062306a36Sopenharmony_ci		if (msglen == sizeof(*vrh))
238162306a36Sopenharmony_ci			adapter->hena = vrh->hena;
238262306a36Sopenharmony_ci		else
238362306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev,
238462306a36Sopenharmony_ci				 "Invalid message %d from PF\n", v_opcode);
238562306a36Sopenharmony_ci		}
238662306a36Sopenharmony_ci		break;
238762306a36Sopenharmony_ci	case VIRTCHNL_OP_REQUEST_QUEUES: {
238862306a36Sopenharmony_ci		struct virtchnl_vf_res_request *vfres =
238962306a36Sopenharmony_ci			(struct virtchnl_vf_res_request *)msg;
239062306a36Sopenharmony_ci
239162306a36Sopenharmony_ci		if (vfres->num_queue_pairs != adapter->num_req_queues) {
239262306a36Sopenharmony_ci			dev_info(&adapter->pdev->dev,
239362306a36Sopenharmony_ci				 "Requested %d queues, PF can support %d\n",
239462306a36Sopenharmony_ci				 adapter->num_req_queues,
239562306a36Sopenharmony_ci				 vfres->num_queue_pairs);
239662306a36Sopenharmony_ci			adapter->num_req_queues = 0;
239762306a36Sopenharmony_ci			adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
239862306a36Sopenharmony_ci		}
239962306a36Sopenharmony_ci		}
240062306a36Sopenharmony_ci		break;
240162306a36Sopenharmony_ci	case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
240262306a36Sopenharmony_ci		struct iavf_cloud_filter *cf;
240362306a36Sopenharmony_ci
240462306a36Sopenharmony_ci		list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
240562306a36Sopenharmony_ci			if (cf->state == __IAVF_CF_ADD_PENDING)
240662306a36Sopenharmony_ci				cf->state = __IAVF_CF_ACTIVE;
240762306a36Sopenharmony_ci		}
240862306a36Sopenharmony_ci		}
240962306a36Sopenharmony_ci		break;
241062306a36Sopenharmony_ci	case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
241162306a36Sopenharmony_ci		struct iavf_cloud_filter *cf, *cftmp;
241262306a36Sopenharmony_ci
241362306a36Sopenharmony_ci		list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
241462306a36Sopenharmony_ci					 list) {
241562306a36Sopenharmony_ci			if (cf->state == __IAVF_CF_DEL_PENDING) {
241662306a36Sopenharmony_ci				cf->state = __IAVF_CF_INVALID;
241762306a36Sopenharmony_ci				list_del(&cf->list);
241862306a36Sopenharmony_ci				kfree(cf);
241962306a36Sopenharmony_ci				adapter->num_cloud_filters--;
242062306a36Sopenharmony_ci			}
242162306a36Sopenharmony_ci		}
242262306a36Sopenharmony_ci		}
242362306a36Sopenharmony_ci		break;
242462306a36Sopenharmony_ci	case VIRTCHNL_OP_ADD_FDIR_FILTER: {
242562306a36Sopenharmony_ci		struct virtchnl_fdir_add *add_fltr = (struct virtchnl_fdir_add *)msg;
242662306a36Sopenharmony_ci		struct iavf_fdir_fltr *fdir, *fdir_tmp;
242762306a36Sopenharmony_ci
242862306a36Sopenharmony_ci		spin_lock_bh(&adapter->fdir_fltr_lock);
242962306a36Sopenharmony_ci		list_for_each_entry_safe(fdir, fdir_tmp,
243062306a36Sopenharmony_ci					 &adapter->fdir_list_head,
243162306a36Sopenharmony_ci					 list) {
243262306a36Sopenharmony_ci			if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING) {
243362306a36Sopenharmony_ci				if (add_fltr->status == VIRTCHNL_FDIR_SUCCESS) {
243462306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is added\n",
243562306a36Sopenharmony_ci						 fdir->loc);
243662306a36Sopenharmony_ci					fdir->state = IAVF_FDIR_FLTR_ACTIVE;
243762306a36Sopenharmony_ci					fdir->flow_id = add_fltr->flow_id;
243862306a36Sopenharmony_ci				} else {
243962306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to add Flow Director filter with status: %d\n",
244062306a36Sopenharmony_ci						 add_fltr->status);
244162306a36Sopenharmony_ci					iavf_print_fdir_fltr(adapter, fdir);
244262306a36Sopenharmony_ci					list_del(&fdir->list);
244362306a36Sopenharmony_ci					kfree(fdir);
244462306a36Sopenharmony_ci					adapter->fdir_active_fltr--;
244562306a36Sopenharmony_ci				}
244662306a36Sopenharmony_ci			}
244762306a36Sopenharmony_ci		}
244862306a36Sopenharmony_ci		spin_unlock_bh(&adapter->fdir_fltr_lock);
244962306a36Sopenharmony_ci		}
245062306a36Sopenharmony_ci		break;
245162306a36Sopenharmony_ci	case VIRTCHNL_OP_DEL_FDIR_FILTER: {
245262306a36Sopenharmony_ci		struct virtchnl_fdir_del *del_fltr = (struct virtchnl_fdir_del *)msg;
245362306a36Sopenharmony_ci		struct iavf_fdir_fltr *fdir, *fdir_tmp;
245462306a36Sopenharmony_ci
245562306a36Sopenharmony_ci		spin_lock_bh(&adapter->fdir_fltr_lock);
245662306a36Sopenharmony_ci		list_for_each_entry_safe(fdir, fdir_tmp, &adapter->fdir_list_head,
245762306a36Sopenharmony_ci					 list) {
245862306a36Sopenharmony_ci			if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) {
245962306a36Sopenharmony_ci				if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS ||
246062306a36Sopenharmony_ci				    del_fltr->status ==
246162306a36Sopenharmony_ci				    VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
246262306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is deleted\n",
246362306a36Sopenharmony_ci						 fdir->loc);
246462306a36Sopenharmony_ci					list_del(&fdir->list);
246562306a36Sopenharmony_ci					kfree(fdir);
246662306a36Sopenharmony_ci					adapter->fdir_active_fltr--;
246762306a36Sopenharmony_ci				} else {
246862306a36Sopenharmony_ci					fdir->state = IAVF_FDIR_FLTR_ACTIVE;
246962306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to delete Flow Director filter with status: %d\n",
247062306a36Sopenharmony_ci						 del_fltr->status);
247162306a36Sopenharmony_ci					iavf_print_fdir_fltr(adapter, fdir);
247262306a36Sopenharmony_ci				}
247362306a36Sopenharmony_ci			} else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) {
247462306a36Sopenharmony_ci				if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS ||
247562306a36Sopenharmony_ci				    del_fltr->status ==
247662306a36Sopenharmony_ci				    VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
247762306a36Sopenharmony_ci					fdir->state = IAVF_FDIR_FLTR_INACTIVE;
247862306a36Sopenharmony_ci				} else {
247962306a36Sopenharmony_ci					fdir->state = IAVF_FDIR_FLTR_ACTIVE;
248062306a36Sopenharmony_ci					dev_info(&adapter->pdev->dev, "Failed to disable Flow Director filter with status: %d\n",
248162306a36Sopenharmony_ci						 del_fltr->status);
248262306a36Sopenharmony_ci					iavf_print_fdir_fltr(adapter, fdir);
248362306a36Sopenharmony_ci				}
248462306a36Sopenharmony_ci			}
248562306a36Sopenharmony_ci		}
248662306a36Sopenharmony_ci		spin_unlock_bh(&adapter->fdir_fltr_lock);
248762306a36Sopenharmony_ci		}
248862306a36Sopenharmony_ci		break;
248962306a36Sopenharmony_ci	case VIRTCHNL_OP_ADD_RSS_CFG: {
249062306a36Sopenharmony_ci		struct iavf_adv_rss *rss;
249162306a36Sopenharmony_ci
249262306a36Sopenharmony_ci		spin_lock_bh(&adapter->adv_rss_lock);
249362306a36Sopenharmony_ci		list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
249462306a36Sopenharmony_ci			if (rss->state == IAVF_ADV_RSS_ADD_PENDING) {
249562306a36Sopenharmony_ci				iavf_print_adv_rss_cfg(adapter, rss,
249662306a36Sopenharmony_ci						       "Input set change for",
249762306a36Sopenharmony_ci						       "successful");
249862306a36Sopenharmony_ci				rss->state = IAVF_ADV_RSS_ACTIVE;
249962306a36Sopenharmony_ci			}
250062306a36Sopenharmony_ci		}
250162306a36Sopenharmony_ci		spin_unlock_bh(&adapter->adv_rss_lock);
250262306a36Sopenharmony_ci		}
250362306a36Sopenharmony_ci		break;
250462306a36Sopenharmony_ci	case VIRTCHNL_OP_DEL_RSS_CFG: {
250562306a36Sopenharmony_ci		struct iavf_adv_rss *rss, *rss_tmp;
250662306a36Sopenharmony_ci
250762306a36Sopenharmony_ci		spin_lock_bh(&adapter->adv_rss_lock);
250862306a36Sopenharmony_ci		list_for_each_entry_safe(rss, rss_tmp,
250962306a36Sopenharmony_ci					 &adapter->adv_rss_list_head, list) {
251062306a36Sopenharmony_ci			if (rss->state == IAVF_ADV_RSS_DEL_PENDING) {
251162306a36Sopenharmony_ci				list_del(&rss->list);
251262306a36Sopenharmony_ci				kfree(rss);
251362306a36Sopenharmony_ci			}
251462306a36Sopenharmony_ci		}
251562306a36Sopenharmony_ci		spin_unlock_bh(&adapter->adv_rss_lock);
251662306a36Sopenharmony_ci		}
251762306a36Sopenharmony_ci		break;
251862306a36Sopenharmony_ci	case VIRTCHNL_OP_ADD_VLAN_V2: {
251962306a36Sopenharmony_ci		struct iavf_vlan_filter *f;
252062306a36Sopenharmony_ci
252162306a36Sopenharmony_ci		spin_lock_bh(&adapter->mac_vlan_list_lock);
252262306a36Sopenharmony_ci		list_for_each_entry(f, &adapter->vlan_filter_list, list) {
252362306a36Sopenharmony_ci			if (f->state == IAVF_VLAN_IS_NEW)
252462306a36Sopenharmony_ci				f->state = IAVF_VLAN_ACTIVE;
252562306a36Sopenharmony_ci		}
252662306a36Sopenharmony_ci		spin_unlock_bh(&adapter->mac_vlan_list_lock);
252762306a36Sopenharmony_ci		}
252862306a36Sopenharmony_ci		break;
252962306a36Sopenharmony_ci	case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
253062306a36Sopenharmony_ci		/* PF enabled vlan strip on this VF.
253162306a36Sopenharmony_ci		 * Update netdev->features if needed to be in sync with ethtool.
253262306a36Sopenharmony_ci		 */
253362306a36Sopenharmony_ci		if (!v_retval)
253462306a36Sopenharmony_ci			iavf_netdev_features_vlan_strip_set(netdev, true);
253562306a36Sopenharmony_ci		break;
253662306a36Sopenharmony_ci	case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
253762306a36Sopenharmony_ci		/* PF disabled vlan strip on this VF.
253862306a36Sopenharmony_ci		 * Update netdev->features if needed to be in sync with ethtool.
253962306a36Sopenharmony_ci		 */
254062306a36Sopenharmony_ci		if (!v_retval)
254162306a36Sopenharmony_ci			iavf_netdev_features_vlan_strip_set(netdev, false);
254262306a36Sopenharmony_ci		break;
254362306a36Sopenharmony_ci	default:
254462306a36Sopenharmony_ci		if (adapter->current_op && (v_opcode != adapter->current_op))
254562306a36Sopenharmony_ci			dev_warn(&adapter->pdev->dev, "Expected response %d from PF, received %d\n",
254662306a36Sopenharmony_ci				 adapter->current_op, v_opcode);
254762306a36Sopenharmony_ci		break;
254862306a36Sopenharmony_ci	} /* switch v_opcode */
254962306a36Sopenharmony_ci	adapter->current_op = VIRTCHNL_OP_UNKNOWN;
255062306a36Sopenharmony_ci}
2551