15ec8b7d1SJesse Brandeburg // SPDX-License-Identifier: GPL-2.0
25ec8b7d1SJesse Brandeburg /* Copyright(c) 2013 - 2018 Intel Corporation. */
35ec8b7d1SJesse Brandeburg
45ec8b7d1SJesse Brandeburg #include "iavf.h"
566bc8e0fSJesse Brandeburg #include "iavf_prototype.h"
65ec8b7d1SJesse Brandeburg #include "iavf_client.h"
75ec8b7d1SJesse Brandeburg
85ec8b7d1SJesse Brandeburg /**
95ec8b7d1SJesse Brandeburg * iavf_send_pf_msg
105ec8b7d1SJesse Brandeburg * @adapter: adapter structure
115ec8b7d1SJesse Brandeburg * @op: virtual channel opcode
125ec8b7d1SJesse Brandeburg * @msg: pointer to message buffer
135ec8b7d1SJesse Brandeburg * @len: message length
145ec8b7d1SJesse Brandeburg *
155ec8b7d1SJesse Brandeburg * Send message to PF and print status if failure.
165ec8b7d1SJesse Brandeburg **/
iavf_send_pf_msg(struct iavf_adapter * adapter,enum virtchnl_ops op,u8 * msg,u16 len)175ec8b7d1SJesse Brandeburg static int iavf_send_pf_msg(struct iavf_adapter *adapter,
185ec8b7d1SJesse Brandeburg enum virtchnl_ops op, u8 *msg, u16 len)
195ec8b7d1SJesse Brandeburg {
20f349daa5SJesse Brandeburg struct iavf_hw *hw = &adapter->hw;
21bae569d0SMateusz Palczewski enum iavf_status status;
225ec8b7d1SJesse Brandeburg
235ec8b7d1SJesse Brandeburg if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
245ec8b7d1SJesse Brandeburg return 0; /* nothing to see here, move along */
255ec8b7d1SJesse Brandeburg
26bae569d0SMateusz Palczewski status = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
27bae569d0SMateusz Palczewski if (status)
28bae569d0SMateusz Palczewski dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, status %s, aq_err %s\n",
29bae569d0SMateusz Palczewski op, iavf_stat_str(hw, status),
305ec8b7d1SJesse Brandeburg iavf_aq_str(hw, hw->aq.asq_last_status));
31bae569d0SMateusz Palczewski return iavf_status_to_errno(status);
325ec8b7d1SJesse Brandeburg }
335ec8b7d1SJesse Brandeburg
345ec8b7d1SJesse Brandeburg /**
355ec8b7d1SJesse Brandeburg * iavf_send_api_ver
365ec8b7d1SJesse Brandeburg * @adapter: adapter structure
375ec8b7d1SJesse Brandeburg *
385ec8b7d1SJesse Brandeburg * Send API version admin queue message to the PF. The reply is not checked
395ec8b7d1SJesse Brandeburg * in this function. Returns 0 if the message was successfully
40fdad1d54SAlice Michael * sent, or one of the IAVF_ADMIN_QUEUE_ERROR_ statuses if not.
415ec8b7d1SJesse Brandeburg **/
iavf_send_api_ver(struct iavf_adapter * adapter)425ec8b7d1SJesse Brandeburg int iavf_send_api_ver(struct iavf_adapter *adapter)
435ec8b7d1SJesse Brandeburg {
445ec8b7d1SJesse Brandeburg struct virtchnl_version_info vvi;
455ec8b7d1SJesse Brandeburg
465ec8b7d1SJesse Brandeburg vvi.major = VIRTCHNL_VERSION_MAJOR;
475ec8b7d1SJesse Brandeburg vvi.minor = VIRTCHNL_VERSION_MINOR;
485ec8b7d1SJesse Brandeburg
495ec8b7d1SJesse Brandeburg return iavf_send_pf_msg(adapter, VIRTCHNL_OP_VERSION, (u8 *)&vvi,
505ec8b7d1SJesse Brandeburg sizeof(vvi));
515ec8b7d1SJesse Brandeburg }
525ec8b7d1SJesse Brandeburg
535ec8b7d1SJesse Brandeburg /**
548fc16be6SMateusz Palczewski * iavf_poll_virtchnl_msg
558fc16be6SMateusz Palczewski * @hw: HW configuration structure
568fc16be6SMateusz Palczewski * @event: event to populate on success
578fc16be6SMateusz Palczewski * @op_to_poll: requested virtchnl op to poll for
588fc16be6SMateusz Palczewski *
598fc16be6SMateusz Palczewski * Initialize poll for virtchnl msg matching the requested_op. Returns 0
608fc16be6SMateusz Palczewski * if a message of the correct opcode is in the queue or an error code
618fc16be6SMateusz Palczewski * if no message matching the op code is waiting and other failures.
628fc16be6SMateusz Palczewski */
638fc16be6SMateusz Palczewski static int
iavf_poll_virtchnl_msg(struct iavf_hw * hw,struct iavf_arq_event_info * event,enum virtchnl_ops op_to_poll)648fc16be6SMateusz Palczewski iavf_poll_virtchnl_msg(struct iavf_hw *hw, struct iavf_arq_event_info *event,
658fc16be6SMateusz Palczewski enum virtchnl_ops op_to_poll)
668fc16be6SMateusz Palczewski {
678fc16be6SMateusz Palczewski enum virtchnl_ops received_op;
688fc16be6SMateusz Palczewski enum iavf_status status;
698fc16be6SMateusz Palczewski u32 v_retval;
708fc16be6SMateusz Palczewski
718fc16be6SMateusz Palczewski while (1) {
728fc16be6SMateusz Palczewski /* When the AQ is empty, iavf_clean_arq_element will return
738fc16be6SMateusz Palczewski * nonzero and this loop will terminate.
748fc16be6SMateusz Palczewski */
758fc16be6SMateusz Palczewski status = iavf_clean_arq_element(hw, event, NULL);
768fc16be6SMateusz Palczewski if (status != IAVF_SUCCESS)
778fc16be6SMateusz Palczewski return iavf_status_to_errno(status);
788fc16be6SMateusz Palczewski received_op =
798fc16be6SMateusz Palczewski (enum virtchnl_ops)le32_to_cpu(event->desc.cookie_high);
808fc16be6SMateusz Palczewski if (op_to_poll == received_op)
818fc16be6SMateusz Palczewski break;
828fc16be6SMateusz Palczewski }
838fc16be6SMateusz Palczewski
848fc16be6SMateusz Palczewski v_retval = le32_to_cpu(event->desc.cookie_low);
858fc16be6SMateusz Palczewski return virtchnl_status_to_errno((enum virtchnl_status_code)v_retval);
868fc16be6SMateusz Palczewski }
878fc16be6SMateusz Palczewski
888fc16be6SMateusz Palczewski /**
895ec8b7d1SJesse Brandeburg * iavf_verify_api_ver
905ec8b7d1SJesse Brandeburg * @adapter: adapter structure
915ec8b7d1SJesse Brandeburg *
925ec8b7d1SJesse Brandeburg * Compare API versions with the PF. Must be called after admin queue is
935ec8b7d1SJesse Brandeburg * initialized. Returns 0 if API versions match, -EIO if they do not,
948821b3faSAlice Michael * IAVF_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty, and any errors
955ec8b7d1SJesse Brandeburg * from the firmware are propagated.
965ec8b7d1SJesse Brandeburg **/
iavf_verify_api_ver(struct iavf_adapter * adapter)975ec8b7d1SJesse Brandeburg int iavf_verify_api_ver(struct iavf_adapter *adapter)
985ec8b7d1SJesse Brandeburg {
997af36e32SAlice Michael struct iavf_arq_event_info event;
1008fc16be6SMateusz Palczewski int err;
1015ec8b7d1SJesse Brandeburg
1025ec8b7d1SJesse Brandeburg event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
1038fc16be6SMateusz Palczewski event.msg_buf = kzalloc(IAVF_MAX_AQ_BUF_SIZE, GFP_KERNEL);
1048fc16be6SMateusz Palczewski if (!event.msg_buf)
1058fc16be6SMateusz Palczewski return -ENOMEM;
1065ec8b7d1SJesse Brandeburg
1078fc16be6SMateusz Palczewski err = iavf_poll_virtchnl_msg(&adapter->hw, &event, VIRTCHNL_OP_VERSION);
1088fc16be6SMateusz Palczewski if (!err) {
1098fc16be6SMateusz Palczewski struct virtchnl_version_info *pf_vvi =
1108fc16be6SMateusz Palczewski (struct virtchnl_version_info *)event.msg_buf;
1115ec8b7d1SJesse Brandeburg adapter->pf_version = *pf_vvi;
1125ec8b7d1SJesse Brandeburg
1138fc16be6SMateusz Palczewski if (pf_vvi->major > VIRTCHNL_VERSION_MAJOR ||
1148fc16be6SMateusz Palczewski (pf_vvi->major == VIRTCHNL_VERSION_MAJOR &&
1158fc16be6SMateusz Palczewski pf_vvi->minor > VIRTCHNL_VERSION_MINOR))
1165ec8b7d1SJesse Brandeburg err = -EIO;
1178fc16be6SMateusz Palczewski }
1185ec8b7d1SJesse Brandeburg
1195ec8b7d1SJesse Brandeburg kfree(event.msg_buf);
1208fc16be6SMateusz Palczewski
1215ec8b7d1SJesse Brandeburg return err;
1225ec8b7d1SJesse Brandeburg }
1235ec8b7d1SJesse Brandeburg
1245ec8b7d1SJesse Brandeburg /**
1255ec8b7d1SJesse Brandeburg * iavf_send_vf_config_msg
1265ec8b7d1SJesse Brandeburg * @adapter: adapter structure
1275ec8b7d1SJesse Brandeburg *
1285ec8b7d1SJesse Brandeburg * Send VF configuration request admin queue message to the PF. The reply
1295ec8b7d1SJesse Brandeburg * is not checked in this function. Returns 0 if the message was
130fdad1d54SAlice Michael * successfully sent, or one of the IAVF_ADMIN_QUEUE_ERROR_ statuses if not.
1315ec8b7d1SJesse Brandeburg **/
iavf_send_vf_config_msg(struct iavf_adapter * adapter)1325ec8b7d1SJesse Brandeburg int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
1335ec8b7d1SJesse Brandeburg {
1345ec8b7d1SJesse Brandeburg u32 caps;
1355ec8b7d1SJesse Brandeburg
1365ec8b7d1SJesse Brandeburg caps = VIRTCHNL_VF_OFFLOAD_L2 |
1375ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_RSS_PF |
1385ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_RSS_AQ |
1395ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_RSS_REG |
1405ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_VLAN |
1415ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_WB_ON_ITR |
1425ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 |
1435ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_ENCAP |
144209f2f9cSBrett Creeley VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
1455ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
1465ec8b7d1SJesse Brandeburg VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
147e0ef26fbSBrett Creeley VIRTCHNL_VF_OFFLOAD_ADQ |
148c91a4f9fSBrett Creeley VIRTCHNL_VF_OFFLOAD_USO |
1490dbfbabbSHaiyue Wang VIRTCHNL_VF_OFFLOAD_FDIR_PF |
1500aaeb4fbSHaiyue Wang VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
151e0ef26fbSBrett Creeley VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
1525ec8b7d1SJesse Brandeburg
1535ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES;
1545ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_GET_CONFIG;
1555ec8b7d1SJesse Brandeburg if (PF_IS_V11(adapter))
1565ec8b7d1SJesse Brandeburg return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_VF_RESOURCES,
1575ec8b7d1SJesse Brandeburg (u8 *)&caps, sizeof(caps));
1585ec8b7d1SJesse Brandeburg else
1595ec8b7d1SJesse Brandeburg return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_VF_RESOURCES,
1605ec8b7d1SJesse Brandeburg NULL, 0);
1615ec8b7d1SJesse Brandeburg }
1625ec8b7d1SJesse Brandeburg
iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter * adapter)163209f2f9cSBrett Creeley int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter)
164209f2f9cSBrett Creeley {
165209f2f9cSBrett Creeley adapter->aq_required &= ~IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS;
166209f2f9cSBrett Creeley
167209f2f9cSBrett Creeley if (!VLAN_V2_ALLOWED(adapter))
168209f2f9cSBrett Creeley return -EOPNOTSUPP;
169209f2f9cSBrett Creeley
170209f2f9cSBrett Creeley adapter->current_op = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
171209f2f9cSBrett Creeley
172209f2f9cSBrett Creeley return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS,
173209f2f9cSBrett Creeley NULL, 0);
174209f2f9cSBrett Creeley }
175209f2f9cSBrett Creeley
1765ec8b7d1SJesse Brandeburg /**
1775ec8b7d1SJesse Brandeburg * iavf_validate_num_queues
1785ec8b7d1SJesse Brandeburg * @adapter: adapter structure
1795ec8b7d1SJesse Brandeburg *
1805ec8b7d1SJesse Brandeburg * Validate that the number of queues the PF has sent in
1815ec8b7d1SJesse Brandeburg * VIRTCHNL_OP_GET_VF_RESOURCES is not larger than the VF can handle.
1825ec8b7d1SJesse Brandeburg **/
iavf_validate_num_queues(struct iavf_adapter * adapter)1835ec8b7d1SJesse Brandeburg static void iavf_validate_num_queues(struct iavf_adapter *adapter)
1845ec8b7d1SJesse Brandeburg {
1855ec8b7d1SJesse Brandeburg if (adapter->vf_res->num_queue_pairs > IAVF_MAX_REQ_QUEUES) {
1865ec8b7d1SJesse Brandeburg struct virtchnl_vsi_resource *vsi_res;
1875ec8b7d1SJesse Brandeburg int i;
1885ec8b7d1SJesse Brandeburg
1895ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Received %d queues, but can only have a max of %d\n",
1905ec8b7d1SJesse Brandeburg adapter->vf_res->num_queue_pairs,
1915ec8b7d1SJesse Brandeburg IAVF_MAX_REQ_QUEUES);
1925ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Fixing by reducing queues to %d\n",
1935ec8b7d1SJesse Brandeburg IAVF_MAX_REQ_QUEUES);
1945ec8b7d1SJesse Brandeburg adapter->vf_res->num_queue_pairs = IAVF_MAX_REQ_QUEUES;
1955ec8b7d1SJesse Brandeburg for (i = 0; i < adapter->vf_res->num_vsis; i++) {
1965ec8b7d1SJesse Brandeburg vsi_res = &adapter->vf_res->vsi_res[i];
1975ec8b7d1SJesse Brandeburg vsi_res->num_queue_pairs = IAVF_MAX_REQ_QUEUES;
1985ec8b7d1SJesse Brandeburg }
1995ec8b7d1SJesse Brandeburg }
2005ec8b7d1SJesse Brandeburg }
2015ec8b7d1SJesse Brandeburg
2025ec8b7d1SJesse Brandeburg /**
2035ec8b7d1SJesse Brandeburg * iavf_get_vf_config
2045ec8b7d1SJesse Brandeburg * @adapter: private adapter structure
2055ec8b7d1SJesse Brandeburg *
2065ec8b7d1SJesse Brandeburg * Get VF configuration from PF and populate hw structure. Must be called after
2075ec8b7d1SJesse Brandeburg * admin queue is initialized. Busy waits until response is received from PF,
2085ec8b7d1SJesse Brandeburg * with maximum timeout. Response from PF is returned in the buffer for further
2095ec8b7d1SJesse Brandeburg * processing by the caller.
2105ec8b7d1SJesse Brandeburg **/
iavf_get_vf_config(struct iavf_adapter * adapter)2115ec8b7d1SJesse Brandeburg int iavf_get_vf_config(struct iavf_adapter *adapter)
2125ec8b7d1SJesse Brandeburg {
213f349daa5SJesse Brandeburg struct iavf_hw *hw = &adapter->hw;
2147af36e32SAlice Michael struct iavf_arq_event_info event;
2155ec8b7d1SJesse Brandeburg u16 len;
2168fc16be6SMateusz Palczewski int err;
2175ec8b7d1SJesse Brandeburg
2185e7f59faSAlexander Lobakin len = IAVF_VIRTCHNL_VF_RESOURCE_SIZE;
2195ec8b7d1SJesse Brandeburg event.buf_len = len;
2208fc16be6SMateusz Palczewski event.msg_buf = kzalloc(len, GFP_KERNEL);
2218fc16be6SMateusz Palczewski if (!event.msg_buf)
2228fc16be6SMateusz Palczewski return -ENOMEM;
2235ec8b7d1SJesse Brandeburg
2248fc16be6SMateusz Palczewski err = iavf_poll_virtchnl_msg(hw, &event, VIRTCHNL_OP_GET_VF_RESOURCES);
2255ec8b7d1SJesse Brandeburg memcpy(adapter->vf_res, event.msg_buf, min(event.msg_len, len));
2265ec8b7d1SJesse Brandeburg
2275ec8b7d1SJesse Brandeburg /* some PFs send more queues than we should have so validate that
2285ec8b7d1SJesse Brandeburg * we aren't getting too many queues
2295ec8b7d1SJesse Brandeburg */
2305ec8b7d1SJesse Brandeburg if (!err)
2315ec8b7d1SJesse Brandeburg iavf_validate_num_queues(adapter);
2325ec8b7d1SJesse Brandeburg iavf_vf_parse_hw_config(hw, adapter->vf_res);
2338fc16be6SMateusz Palczewski
2345ec8b7d1SJesse Brandeburg kfree(event.msg_buf);
2358fc16be6SMateusz Palczewski
2365ec8b7d1SJesse Brandeburg return err;
2375ec8b7d1SJesse Brandeburg }
2385ec8b7d1SJesse Brandeburg
iavf_get_vf_vlan_v2_caps(struct iavf_adapter * adapter)239209f2f9cSBrett Creeley int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
240209f2f9cSBrett Creeley {
241209f2f9cSBrett Creeley struct iavf_arq_event_info event;
2428fc16be6SMateusz Palczewski int err;
243209f2f9cSBrett Creeley u16 len;
244209f2f9cSBrett Creeley
245209f2f9cSBrett Creeley len = sizeof(struct virtchnl_vlan_caps);
246209f2f9cSBrett Creeley event.buf_len = len;
2478fc16be6SMateusz Palczewski event.msg_buf = kzalloc(len, GFP_KERNEL);
2488fc16be6SMateusz Palczewski if (!event.msg_buf)
2498fc16be6SMateusz Palczewski return -ENOMEM;
250209f2f9cSBrett Creeley
2518fc16be6SMateusz Palczewski err = iavf_poll_virtchnl_msg(&adapter->hw, &event,
2528fc16be6SMateusz Palczewski VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS);
2538fc16be6SMateusz Palczewski if (!err)
2548fc16be6SMateusz Palczewski memcpy(&adapter->vlan_v2_caps, event.msg_buf,
2558fc16be6SMateusz Palczewski min(event.msg_len, len));
256209f2f9cSBrett Creeley
257209f2f9cSBrett Creeley kfree(event.msg_buf);
2588fc16be6SMateusz Palczewski
259209f2f9cSBrett Creeley return err;
260209f2f9cSBrett Creeley }
261209f2f9cSBrett Creeley
2625ec8b7d1SJesse Brandeburg /**
2635ec8b7d1SJesse Brandeburg * iavf_configure_queues
2645ec8b7d1SJesse Brandeburg * @adapter: adapter structure
2655ec8b7d1SJesse Brandeburg *
2665ec8b7d1SJesse Brandeburg * Request that the PF set up our (previously allocated) queues.
2675ec8b7d1SJesse Brandeburg **/
iavf_configure_queues(struct iavf_adapter * adapter)2685ec8b7d1SJesse Brandeburg void iavf_configure_queues(struct iavf_adapter *adapter)
2695ec8b7d1SJesse Brandeburg {
2705ec8b7d1SJesse Brandeburg struct virtchnl_vsi_queue_config_info *vqci;
271399c98c4SMichal Jaron int i, max_frame = adapter->vf_res->max_mtu;
2725ec8b7d1SJesse Brandeburg int pairs = adapter->num_active_queues;
273399c98c4SMichal Jaron struct virtchnl_queue_pair_info *vqpi;
274af07adbbSGustavo A. R. Silva size_t len;
2755ec8b7d1SJesse Brandeburg
276399c98c4SMichal Jaron if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
277399c98c4SMichal Jaron max_frame = IAVF_MAX_RXBUFFER;
278399c98c4SMichal Jaron
2795ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
2805ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
2815ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
2825ec8b7d1SJesse Brandeburg adapter->current_op);
2835ec8b7d1SJesse Brandeburg return;
2845ec8b7d1SJesse Brandeburg }
2855ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
2865e7f59faSAlexander Lobakin len = virtchnl_struct_size(vqci, qpair, pairs);
2875ec8b7d1SJesse Brandeburg vqci = kzalloc(len, GFP_KERNEL);
2885ec8b7d1SJesse Brandeburg if (!vqci)
2895ec8b7d1SJesse Brandeburg return;
2905ec8b7d1SJesse Brandeburg
2915ec8b7d1SJesse Brandeburg /* Limit maximum frame size when jumbo frames is not enabled */
2925ec8b7d1SJesse Brandeburg if (!(adapter->flags & IAVF_FLAG_LEGACY_RX) &&
2935ec8b7d1SJesse Brandeburg (adapter->netdev->mtu <= ETH_DATA_LEN))
29456184e01SJesse Brandeburg max_frame = IAVF_RXBUFFER_1536 - NET_IP_ALIGN;
2955ec8b7d1SJesse Brandeburg
2965ec8b7d1SJesse Brandeburg vqci->vsi_id = adapter->vsi_res->vsi_id;
2975ec8b7d1SJesse Brandeburg vqci->num_queue_pairs = pairs;
2985ec8b7d1SJesse Brandeburg vqpi = vqci->qpair;
2995ec8b7d1SJesse Brandeburg /* Size check is not needed here - HW max is 16 queue pairs, and we
3005ec8b7d1SJesse Brandeburg * can fit info for 31 of them into the AQ buffer before it overflows.
3015ec8b7d1SJesse Brandeburg */
3025ec8b7d1SJesse Brandeburg for (i = 0; i < pairs; i++) {
3035ec8b7d1SJesse Brandeburg vqpi->txq.vsi_id = vqci->vsi_id;
3045ec8b7d1SJesse Brandeburg vqpi->txq.queue_id = i;
3055ec8b7d1SJesse Brandeburg vqpi->txq.ring_len = adapter->tx_rings[i].count;
3065ec8b7d1SJesse Brandeburg vqpi->txq.dma_ring_addr = adapter->tx_rings[i].dma;
3075ec8b7d1SJesse Brandeburg vqpi->rxq.vsi_id = vqci->vsi_id;
3085ec8b7d1SJesse Brandeburg vqpi->rxq.queue_id = i;
3095ec8b7d1SJesse Brandeburg vqpi->rxq.ring_len = adapter->rx_rings[i].count;
3105ec8b7d1SJesse Brandeburg vqpi->rxq.dma_ring_addr = adapter->rx_rings[i].dma;
3115ec8b7d1SJesse Brandeburg vqpi->rxq.max_pkt_size = max_frame;
3125ec8b7d1SJesse Brandeburg vqpi->rxq.databuffer_size =
3135ec8b7d1SJesse Brandeburg ALIGN(adapter->rx_rings[i].rx_buf_len,
31456184e01SJesse Brandeburg BIT_ULL(IAVF_RXQ_CTX_DBUFF_SHIFT));
3155ec8b7d1SJesse Brandeburg vqpi++;
3165ec8b7d1SJesse Brandeburg }
3175ec8b7d1SJesse Brandeburg
3185ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_QUEUES;
3195ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
3205ec8b7d1SJesse Brandeburg (u8 *)vqci, len);
3215ec8b7d1SJesse Brandeburg kfree(vqci);
3225ec8b7d1SJesse Brandeburg }
3235ec8b7d1SJesse Brandeburg
3245ec8b7d1SJesse Brandeburg /**
3255ec8b7d1SJesse Brandeburg * iavf_enable_queues
3265ec8b7d1SJesse Brandeburg * @adapter: adapter structure
3275ec8b7d1SJesse Brandeburg *
3285ec8b7d1SJesse Brandeburg * Request that the PF enable all of our queues.
3295ec8b7d1SJesse Brandeburg **/
iavf_enable_queues(struct iavf_adapter * adapter)3305ec8b7d1SJesse Brandeburg void iavf_enable_queues(struct iavf_adapter *adapter)
3315ec8b7d1SJesse Brandeburg {
3325ec8b7d1SJesse Brandeburg struct virtchnl_queue_select vqs;
3335ec8b7d1SJesse Brandeburg
3345ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
3355ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
3365ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot enable queues, command %d pending\n",
3375ec8b7d1SJesse Brandeburg adapter->current_op);
3385ec8b7d1SJesse Brandeburg return;
3395ec8b7d1SJesse Brandeburg }
3405ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ENABLE_QUEUES;
3415ec8b7d1SJesse Brandeburg vqs.vsi_id = adapter->vsi_res->vsi_id;
3425ec8b7d1SJesse Brandeburg vqs.tx_queues = BIT(adapter->num_active_queues) - 1;
3435ec8b7d1SJesse Brandeburg vqs.rx_queues = vqs.tx_queues;
3445ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_QUEUES;
3455ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_QUEUES,
3465ec8b7d1SJesse Brandeburg (u8 *)&vqs, sizeof(vqs));
3475ec8b7d1SJesse Brandeburg }
3485ec8b7d1SJesse Brandeburg
3495ec8b7d1SJesse Brandeburg /**
3505ec8b7d1SJesse Brandeburg * iavf_disable_queues
3515ec8b7d1SJesse Brandeburg * @adapter: adapter structure
3525ec8b7d1SJesse Brandeburg *
3535ec8b7d1SJesse Brandeburg * Request that the PF disable all of our queues.
3545ec8b7d1SJesse Brandeburg **/
iavf_disable_queues(struct iavf_adapter * adapter)3555ec8b7d1SJesse Brandeburg void iavf_disable_queues(struct iavf_adapter *adapter)
3565ec8b7d1SJesse Brandeburg {
3575ec8b7d1SJesse Brandeburg struct virtchnl_queue_select vqs;
3585ec8b7d1SJesse Brandeburg
3595ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
3605ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
3615ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot disable queues, command %d pending\n",
3625ec8b7d1SJesse Brandeburg adapter->current_op);
3635ec8b7d1SJesse Brandeburg return;
3645ec8b7d1SJesse Brandeburg }
3655ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DISABLE_QUEUES;
3665ec8b7d1SJesse Brandeburg vqs.vsi_id = adapter->vsi_res->vsi_id;
3675ec8b7d1SJesse Brandeburg vqs.tx_queues = BIT(adapter->num_active_queues) - 1;
3685ec8b7d1SJesse Brandeburg vqs.rx_queues = vqs.tx_queues;
3695ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_QUEUES;
3705ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_QUEUES,
3715ec8b7d1SJesse Brandeburg (u8 *)&vqs, sizeof(vqs));
3725ec8b7d1SJesse Brandeburg }
3735ec8b7d1SJesse Brandeburg
3745ec8b7d1SJesse Brandeburg /**
3755ec8b7d1SJesse Brandeburg * iavf_map_queues
3765ec8b7d1SJesse Brandeburg * @adapter: adapter structure
3775ec8b7d1SJesse Brandeburg *
3785ec8b7d1SJesse Brandeburg * Request that the PF map queues to interrupt vectors. Misc causes, including
3795ec8b7d1SJesse Brandeburg * admin queue, are always mapped to vector 0.
3805ec8b7d1SJesse Brandeburg **/
iavf_map_queues(struct iavf_adapter * adapter)3815ec8b7d1SJesse Brandeburg void iavf_map_queues(struct iavf_adapter *adapter)
3825ec8b7d1SJesse Brandeburg {
3835ec8b7d1SJesse Brandeburg struct virtchnl_irq_map_info *vimi;
3845ec8b7d1SJesse Brandeburg struct virtchnl_vector_map *vecmap;
38556184e01SJesse Brandeburg struct iavf_q_vector *q_vector;
386af07adbbSGustavo A. R. Silva int v_idx, q_vectors;
387af07adbbSGustavo A. R. Silva size_t len;
3885ec8b7d1SJesse Brandeburg
3895ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
3905ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
3915ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot map queues to vectors, command %d pending\n",
3925ec8b7d1SJesse Brandeburg adapter->current_op);
3935ec8b7d1SJesse Brandeburg return;
3945ec8b7d1SJesse Brandeburg }
3955ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_CONFIG_IRQ_MAP;
3965ec8b7d1SJesse Brandeburg
3975ec8b7d1SJesse Brandeburg q_vectors = adapter->num_msix_vectors - NONQ_VECS;
3985ec8b7d1SJesse Brandeburg
3995e7f59faSAlexander Lobakin len = virtchnl_struct_size(vimi, vecmap, adapter->num_msix_vectors);
4005ec8b7d1SJesse Brandeburg vimi = kzalloc(len, GFP_KERNEL);
4015ec8b7d1SJesse Brandeburg if (!vimi)
4025ec8b7d1SJesse Brandeburg return;
4035ec8b7d1SJesse Brandeburg
4045ec8b7d1SJesse Brandeburg vimi->num_vectors = adapter->num_msix_vectors;
4055ec8b7d1SJesse Brandeburg /* Queue vectors first */
4065ec8b7d1SJesse Brandeburg for (v_idx = 0; v_idx < q_vectors; v_idx++) {
4075ec8b7d1SJesse Brandeburg q_vector = &adapter->q_vectors[v_idx];
4085ec8b7d1SJesse Brandeburg vecmap = &vimi->vecmap[v_idx];
4095ec8b7d1SJesse Brandeburg
4105ec8b7d1SJesse Brandeburg vecmap->vsi_id = adapter->vsi_res->vsi_id;
4115ec8b7d1SJesse Brandeburg vecmap->vector_id = v_idx + NONQ_VECS;
4125ec8b7d1SJesse Brandeburg vecmap->txq_map = q_vector->ring_mask;
4135ec8b7d1SJesse Brandeburg vecmap->rxq_map = q_vector->ring_mask;
41456184e01SJesse Brandeburg vecmap->rxitr_idx = IAVF_RX_ITR;
41556184e01SJesse Brandeburg vecmap->txitr_idx = IAVF_TX_ITR;
4165ec8b7d1SJesse Brandeburg }
4175ec8b7d1SJesse Brandeburg /* Misc vector last - this is only for AdminQ messages */
4185ec8b7d1SJesse Brandeburg vecmap = &vimi->vecmap[v_idx];
4195ec8b7d1SJesse Brandeburg vecmap->vsi_id = adapter->vsi_res->vsi_id;
4205ec8b7d1SJesse Brandeburg vecmap->vector_id = 0;
4215ec8b7d1SJesse Brandeburg vecmap->txq_map = 0;
4225ec8b7d1SJesse Brandeburg vecmap->rxq_map = 0;
4235ec8b7d1SJesse Brandeburg
4245ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_MAP_VECTORS;
4255ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_IRQ_MAP,
4265ec8b7d1SJesse Brandeburg (u8 *)vimi, len);
4275ec8b7d1SJesse Brandeburg kfree(vimi);
4285ec8b7d1SJesse Brandeburg }
4295ec8b7d1SJesse Brandeburg
4305ec8b7d1SJesse Brandeburg /**
431a3e839d5SMateusz Palczewski * iavf_set_mac_addr_type - Set the correct request type from the filter type
432a3e839d5SMateusz Palczewski * @virtchnl_ether_addr: pointer to requested list element
433a3e839d5SMateusz Palczewski * @filter: pointer to requested filter
434a3e839d5SMateusz Palczewski **/
435a3e839d5SMateusz Palczewski static void
iavf_set_mac_addr_type(struct virtchnl_ether_addr * virtchnl_ether_addr,const struct iavf_mac_filter * filter)436a3e839d5SMateusz Palczewski iavf_set_mac_addr_type(struct virtchnl_ether_addr *virtchnl_ether_addr,
437a3e839d5SMateusz Palczewski const struct iavf_mac_filter *filter)
438a3e839d5SMateusz Palczewski {
439a3e839d5SMateusz Palczewski virtchnl_ether_addr->type = filter->is_primary ?
440a3e839d5SMateusz Palczewski VIRTCHNL_ETHER_ADDR_PRIMARY :
441a3e839d5SMateusz Palczewski VIRTCHNL_ETHER_ADDR_EXTRA;
442a3e839d5SMateusz Palczewski }
443a3e839d5SMateusz Palczewski
444a3e839d5SMateusz Palczewski /**
4455ec8b7d1SJesse Brandeburg * iavf_add_ether_addrs
4465ec8b7d1SJesse Brandeburg * @adapter: adapter structure
4475ec8b7d1SJesse Brandeburg *
4485ec8b7d1SJesse Brandeburg * Request that the PF add one or more addresses to our filters.
4495ec8b7d1SJesse Brandeburg **/
iavf_add_ether_addrs(struct iavf_adapter * adapter)4505ec8b7d1SJesse Brandeburg void iavf_add_ether_addrs(struct iavf_adapter *adapter)
4515ec8b7d1SJesse Brandeburg {
4525ec8b7d1SJesse Brandeburg struct virtchnl_ether_addr_list *veal;
4535ec8b7d1SJesse Brandeburg struct iavf_mac_filter *f;
454af07adbbSGustavo A. R. Silva int i = 0, count = 0;
4555ec8b7d1SJesse Brandeburg bool more = false;
456af07adbbSGustavo A. R. Silva size_t len;
4575ec8b7d1SJesse Brandeburg
4585ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
4595ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
4605ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot add filters, command %d pending\n",
4615ec8b7d1SJesse Brandeburg adapter->current_op);
4625ec8b7d1SJesse Brandeburg return;
4635ec8b7d1SJesse Brandeburg }
4645ec8b7d1SJesse Brandeburg
4655ec8b7d1SJesse Brandeburg spin_lock_bh(&adapter->mac_vlan_list_lock);
4665ec8b7d1SJesse Brandeburg
4675ec8b7d1SJesse Brandeburg list_for_each_entry(f, &adapter->mac_filter_list, list) {
4685ec8b7d1SJesse Brandeburg if (f->add)
4695ec8b7d1SJesse Brandeburg count++;
4705ec8b7d1SJesse Brandeburg }
4715ec8b7d1SJesse Brandeburg if (!count) {
4725ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
4735ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
4745ec8b7d1SJesse Brandeburg return;
4755ec8b7d1SJesse Brandeburg }
4765ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
4775ec8b7d1SJesse Brandeburg
4785e7f59faSAlexander Lobakin len = virtchnl_struct_size(veal, list, count);
4795ec8b7d1SJesse Brandeburg if (len > IAVF_MAX_AQ_BUF_SIZE) {
4805ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev, "Too many add MAC changes in one request\n");
4815e7f59faSAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
4825e7f59faSAlexander Lobakin len = virtchnl_struct_size(veal, list, --count);
4835ec8b7d1SJesse Brandeburg more = true;
4845ec8b7d1SJesse Brandeburg }
4855ec8b7d1SJesse Brandeburg
4865ec8b7d1SJesse Brandeburg veal = kzalloc(len, GFP_ATOMIC);
4875ec8b7d1SJesse Brandeburg if (!veal) {
4885ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
4895ec8b7d1SJesse Brandeburg return;
4905ec8b7d1SJesse Brandeburg }
4915ec8b7d1SJesse Brandeburg
4925ec8b7d1SJesse Brandeburg veal->vsi_id = adapter->vsi_res->vsi_id;
4935ec8b7d1SJesse Brandeburg veal->num_elements = count;
4945ec8b7d1SJesse Brandeburg list_for_each_entry(f, &adapter->mac_filter_list, list) {
4955ec8b7d1SJesse Brandeburg if (f->add) {
4965ec8b7d1SJesse Brandeburg ether_addr_copy(veal->list[i].addr, f->macaddr);
497a3e839d5SMateusz Palczewski iavf_set_mac_addr_type(&veal->list[i], f);
4985ec8b7d1SJesse Brandeburg i++;
4995ec8b7d1SJesse Brandeburg f->add = false;
5005ec8b7d1SJesse Brandeburg if (i == count)
5015ec8b7d1SJesse Brandeburg break;
5025ec8b7d1SJesse Brandeburg }
5035ec8b7d1SJesse Brandeburg }
5045ec8b7d1SJesse Brandeburg if (!more)
5055ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
5065ec8b7d1SJesse Brandeburg
5075ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
5085ec8b7d1SJesse Brandeburg
5095ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
5105ec8b7d1SJesse Brandeburg kfree(veal);
5115ec8b7d1SJesse Brandeburg }
5125ec8b7d1SJesse Brandeburg
5135ec8b7d1SJesse Brandeburg /**
5145ec8b7d1SJesse Brandeburg * iavf_del_ether_addrs
5155ec8b7d1SJesse Brandeburg * @adapter: adapter structure
5165ec8b7d1SJesse Brandeburg *
5175ec8b7d1SJesse Brandeburg * Request that the PF remove one or more addresses from our filters.
5185ec8b7d1SJesse Brandeburg **/
iavf_del_ether_addrs(struct iavf_adapter * adapter)5195ec8b7d1SJesse Brandeburg void iavf_del_ether_addrs(struct iavf_adapter *adapter)
5205ec8b7d1SJesse Brandeburg {
5215ec8b7d1SJesse Brandeburg struct virtchnl_ether_addr_list *veal;
5225ec8b7d1SJesse Brandeburg struct iavf_mac_filter *f, *ftmp;
523af07adbbSGustavo A. R. Silva int i = 0, count = 0;
5245ec8b7d1SJesse Brandeburg bool more = false;
525af07adbbSGustavo A. R. Silva size_t len;
5265ec8b7d1SJesse Brandeburg
5275ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
5285ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
5295ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot remove filters, command %d pending\n",
5305ec8b7d1SJesse Brandeburg adapter->current_op);
5315ec8b7d1SJesse Brandeburg return;
5325ec8b7d1SJesse Brandeburg }
5335ec8b7d1SJesse Brandeburg
5345ec8b7d1SJesse Brandeburg spin_lock_bh(&adapter->mac_vlan_list_lock);
5355ec8b7d1SJesse Brandeburg
5365ec8b7d1SJesse Brandeburg list_for_each_entry(f, &adapter->mac_filter_list, list) {
5375ec8b7d1SJesse Brandeburg if (f->remove)
5385ec8b7d1SJesse Brandeburg count++;
5395ec8b7d1SJesse Brandeburg }
5405ec8b7d1SJesse Brandeburg if (!count) {
5415ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_MAC_FILTER;
5425ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
5435ec8b7d1SJesse Brandeburg return;
5445ec8b7d1SJesse Brandeburg }
5455ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DEL_ETH_ADDR;
5465ec8b7d1SJesse Brandeburg
5475e7f59faSAlexander Lobakin len = virtchnl_struct_size(veal, list, count);
5485ec8b7d1SJesse Brandeburg if (len > IAVF_MAX_AQ_BUF_SIZE) {
5495ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev, "Too many delete MAC changes in one request\n");
5505e7f59faSAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
5515e7f59faSAlexander Lobakin len = virtchnl_struct_size(veal, list, --count);
5525ec8b7d1SJesse Brandeburg more = true;
5535ec8b7d1SJesse Brandeburg }
5545ec8b7d1SJesse Brandeburg veal = kzalloc(len, GFP_ATOMIC);
5555ec8b7d1SJesse Brandeburg if (!veal) {
5565ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
5575ec8b7d1SJesse Brandeburg return;
5585ec8b7d1SJesse Brandeburg }
5595ec8b7d1SJesse Brandeburg
5605ec8b7d1SJesse Brandeburg veal->vsi_id = adapter->vsi_res->vsi_id;
5615ec8b7d1SJesse Brandeburg veal->num_elements = count;
5625ec8b7d1SJesse Brandeburg list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
5635ec8b7d1SJesse Brandeburg if (f->remove) {
5645ec8b7d1SJesse Brandeburg ether_addr_copy(veal->list[i].addr, f->macaddr);
565a3e839d5SMateusz Palczewski iavf_set_mac_addr_type(&veal->list[i], f);
5665ec8b7d1SJesse Brandeburg i++;
5675ec8b7d1SJesse Brandeburg list_del(&f->list);
5685ec8b7d1SJesse Brandeburg kfree(f);
5695ec8b7d1SJesse Brandeburg if (i == count)
5705ec8b7d1SJesse Brandeburg break;
5715ec8b7d1SJesse Brandeburg }
5725ec8b7d1SJesse Brandeburg }
5735ec8b7d1SJesse Brandeburg if (!more)
5745ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_MAC_FILTER;
5755ec8b7d1SJesse Brandeburg
5765ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
5775ec8b7d1SJesse Brandeburg
5785ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_ETH_ADDR, (u8 *)veal, len);
5795ec8b7d1SJesse Brandeburg kfree(veal);
5805ec8b7d1SJesse Brandeburg }
5815ec8b7d1SJesse Brandeburg
5825ec8b7d1SJesse Brandeburg /**
5838da80c9dSSylwester Dziedziuch * iavf_mac_add_ok
5848da80c9dSSylwester Dziedziuch * @adapter: adapter structure
5858da80c9dSSylwester Dziedziuch *
5868da80c9dSSylwester Dziedziuch * Submit list of filters based on PF response.
5878da80c9dSSylwester Dziedziuch **/
iavf_mac_add_ok(struct iavf_adapter * adapter)5888da80c9dSSylwester Dziedziuch static void iavf_mac_add_ok(struct iavf_adapter *adapter)
5898da80c9dSSylwester Dziedziuch {
5908da80c9dSSylwester Dziedziuch struct iavf_mac_filter *f, *ftmp;
5918da80c9dSSylwester Dziedziuch
5928da80c9dSSylwester Dziedziuch spin_lock_bh(&adapter->mac_vlan_list_lock);
5938da80c9dSSylwester Dziedziuch list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
5948da80c9dSSylwester Dziedziuch f->is_new_mac = false;
59535a2443dSMateusz Palczewski if (!f->add && !f->add_handled)
59635a2443dSMateusz Palczewski f->add_handled = true;
5978da80c9dSSylwester Dziedziuch }
5988da80c9dSSylwester Dziedziuch spin_unlock_bh(&adapter->mac_vlan_list_lock);
5998da80c9dSSylwester Dziedziuch }
6008da80c9dSSylwester Dziedziuch
6018da80c9dSSylwester Dziedziuch /**
6028da80c9dSSylwester Dziedziuch * iavf_mac_add_reject
6038da80c9dSSylwester Dziedziuch * @adapter: adapter structure
6048da80c9dSSylwester Dziedziuch *
6058da80c9dSSylwester Dziedziuch * Remove filters from list based on PF response.
6068da80c9dSSylwester Dziedziuch **/
iavf_mac_add_reject(struct iavf_adapter * adapter)6078da80c9dSSylwester Dziedziuch static void iavf_mac_add_reject(struct iavf_adapter *adapter)
6088da80c9dSSylwester Dziedziuch {
6098da80c9dSSylwester Dziedziuch struct net_device *netdev = adapter->netdev;
6108da80c9dSSylwester Dziedziuch struct iavf_mac_filter *f, *ftmp;
6118da80c9dSSylwester Dziedziuch
6128da80c9dSSylwester Dziedziuch spin_lock_bh(&adapter->mac_vlan_list_lock);
6138da80c9dSSylwester Dziedziuch list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
6148da80c9dSSylwester Dziedziuch if (f->remove && ether_addr_equal(f->macaddr, netdev->dev_addr))
6158da80c9dSSylwester Dziedziuch f->remove = false;
6168da80c9dSSylwester Dziedziuch
61735a2443dSMateusz Palczewski if (!f->add && !f->add_handled)
61835a2443dSMateusz Palczewski f->add_handled = true;
61935a2443dSMateusz Palczewski
6208da80c9dSSylwester Dziedziuch if (f->is_new_mac) {
6218da80c9dSSylwester Dziedziuch list_del(&f->list);
6228da80c9dSSylwester Dziedziuch kfree(f);
6238da80c9dSSylwester Dziedziuch }
6248da80c9dSSylwester Dziedziuch }
6258da80c9dSSylwester Dziedziuch spin_unlock_bh(&adapter->mac_vlan_list_lock);
6268da80c9dSSylwester Dziedziuch }
6278da80c9dSSylwester Dziedziuch
6288da80c9dSSylwester Dziedziuch /**
629968996c0SPrzemyslaw Patynowski * iavf_vlan_add_reject
630968996c0SPrzemyslaw Patynowski * @adapter: adapter structure
631968996c0SPrzemyslaw Patynowski *
632968996c0SPrzemyslaw Patynowski * Remove VLAN filters from list based on PF response.
633968996c0SPrzemyslaw Patynowski **/
iavf_vlan_add_reject(struct iavf_adapter * adapter)634968996c0SPrzemyslaw Patynowski static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
635968996c0SPrzemyslaw Patynowski {
636968996c0SPrzemyslaw Patynowski struct iavf_vlan_filter *f, *ftmp;
637968996c0SPrzemyslaw Patynowski
638968996c0SPrzemyslaw Patynowski spin_lock_bh(&adapter->mac_vlan_list_lock);
639968996c0SPrzemyslaw Patynowski list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
6400c0da0e9SAhmed Zaki if (f->state == IAVF_VLAN_IS_NEW) {
641968996c0SPrzemyslaw Patynowski list_del(&f->list);
642968996c0SPrzemyslaw Patynowski kfree(f);
6439c85b7faSAhmed Zaki adapter->num_vlan_filters--;
644968996c0SPrzemyslaw Patynowski }
645968996c0SPrzemyslaw Patynowski }
646968996c0SPrzemyslaw Patynowski spin_unlock_bh(&adapter->mac_vlan_list_lock);
647968996c0SPrzemyslaw Patynowski }
648968996c0SPrzemyslaw Patynowski
649968996c0SPrzemyslaw Patynowski /**
6505ec8b7d1SJesse Brandeburg * iavf_add_vlans
6515ec8b7d1SJesse Brandeburg * @adapter: adapter structure
6525ec8b7d1SJesse Brandeburg *
6535ec8b7d1SJesse Brandeburg * Request that the PF add one or more VLAN filters to our VSI.
6545ec8b7d1SJesse Brandeburg **/
iavf_add_vlans(struct iavf_adapter * adapter)6555ec8b7d1SJesse Brandeburg void iavf_add_vlans(struct iavf_adapter *adapter)
6565ec8b7d1SJesse Brandeburg {
6575ec8b7d1SJesse Brandeburg int len, i = 0, count = 0;
6585ec8b7d1SJesse Brandeburg struct iavf_vlan_filter *f;
6595ec8b7d1SJesse Brandeburg bool more = false;
6605ec8b7d1SJesse Brandeburg
6615ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
6625ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
6635ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot add VLANs, command %d pending\n",
6645ec8b7d1SJesse Brandeburg adapter->current_op);
6655ec8b7d1SJesse Brandeburg return;
6665ec8b7d1SJesse Brandeburg }
6675ec8b7d1SJesse Brandeburg
6685ec8b7d1SJesse Brandeburg spin_lock_bh(&adapter->mac_vlan_list_lock);
6695ec8b7d1SJesse Brandeburg
6705ec8b7d1SJesse Brandeburg list_for_each_entry(f, &adapter->vlan_filter_list, list) {
6710c0da0e9SAhmed Zaki if (f->state == IAVF_VLAN_ADD)
6725ec8b7d1SJesse Brandeburg count++;
6735ec8b7d1SJesse Brandeburg }
67448ccc43eSBrett Creeley if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
6755ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
6765ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
6775ec8b7d1SJesse Brandeburg return;
6785ec8b7d1SJesse Brandeburg }
67948ccc43eSBrett Creeley
68048ccc43eSBrett Creeley if (VLAN_ALLOWED(adapter)) {
68148ccc43eSBrett Creeley struct virtchnl_vlan_filter_list *vvfl;
68248ccc43eSBrett Creeley
6835ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ADD_VLAN;
6845ec8b7d1SJesse Brandeburg
6855e7f59faSAlexander Lobakin len = virtchnl_struct_size(vvfl, vlan_id, count);
6865ec8b7d1SJesse Brandeburg if (len > IAVF_MAX_AQ_BUF_SIZE) {
6875ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
6885e7f59faSAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
6895e7f59faSAlexander Lobakin len = virtchnl_struct_size(vvfl, vlan_id,
6905e7f59faSAlexander Lobakin --count);
6915ec8b7d1SJesse Brandeburg more = true;
6925ec8b7d1SJesse Brandeburg }
6935ec8b7d1SJesse Brandeburg vvfl = kzalloc(len, GFP_ATOMIC);
6945ec8b7d1SJesse Brandeburg if (!vvfl) {
6955ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
6965ec8b7d1SJesse Brandeburg return;
6975ec8b7d1SJesse Brandeburg }
6985ec8b7d1SJesse Brandeburg
6995ec8b7d1SJesse Brandeburg vvfl->vsi_id = adapter->vsi_res->vsi_id;
7005ec8b7d1SJesse Brandeburg vvfl->num_elements = count;
7015ec8b7d1SJesse Brandeburg list_for_each_entry(f, &adapter->vlan_filter_list, list) {
7020c0da0e9SAhmed Zaki if (f->state == IAVF_VLAN_ADD) {
70348ccc43eSBrett Creeley vvfl->vlan_id[i] = f->vlan.vid;
7045ec8b7d1SJesse Brandeburg i++;
7050c0da0e9SAhmed Zaki f->state = IAVF_VLAN_IS_NEW;
7065ec8b7d1SJesse Brandeburg if (i == count)
7075ec8b7d1SJesse Brandeburg break;
7085ec8b7d1SJesse Brandeburg }
7095ec8b7d1SJesse Brandeburg }
7105ec8b7d1SJesse Brandeburg if (!more)
7115ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
7125ec8b7d1SJesse Brandeburg
7135ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
7145ec8b7d1SJesse Brandeburg
7155ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
7165ec8b7d1SJesse Brandeburg kfree(vvfl);
71748ccc43eSBrett Creeley } else {
718968996c0SPrzemyslaw Patynowski u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
719968996c0SPrzemyslaw Patynowski u16 current_vlans = iavf_get_num_vlans_added(adapter);
72048ccc43eSBrett Creeley struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
72148ccc43eSBrett Creeley
72248ccc43eSBrett Creeley adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
72348ccc43eSBrett Creeley
724968996c0SPrzemyslaw Patynowski if ((count + current_vlans) > max_vlans &&
725968996c0SPrzemyslaw Patynowski current_vlans < max_vlans) {
726968996c0SPrzemyslaw Patynowski count = max_vlans - iavf_get_num_vlans_added(adapter);
727968996c0SPrzemyslaw Patynowski more = true;
728968996c0SPrzemyslaw Patynowski }
729968996c0SPrzemyslaw Patynowski
730b0654e64SAlexander Lobakin len = virtchnl_struct_size(vvfl_v2, filters, count);
73148ccc43eSBrett Creeley if (len > IAVF_MAX_AQ_BUF_SIZE) {
73248ccc43eSBrett Creeley dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
733b0654e64SAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
734b0654e64SAlexander Lobakin len = virtchnl_struct_size(vvfl_v2, filters,
735b0654e64SAlexander Lobakin --count);
73648ccc43eSBrett Creeley more = true;
73748ccc43eSBrett Creeley }
73848ccc43eSBrett Creeley
73948ccc43eSBrett Creeley vvfl_v2 = kzalloc(len, GFP_ATOMIC);
74048ccc43eSBrett Creeley if (!vvfl_v2) {
74148ccc43eSBrett Creeley spin_unlock_bh(&adapter->mac_vlan_list_lock);
74248ccc43eSBrett Creeley return;
74348ccc43eSBrett Creeley }
74448ccc43eSBrett Creeley
74548ccc43eSBrett Creeley vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
74648ccc43eSBrett Creeley vvfl_v2->num_elements = count;
74748ccc43eSBrett Creeley list_for_each_entry(f, &adapter->vlan_filter_list, list) {
7480c0da0e9SAhmed Zaki if (f->state == IAVF_VLAN_ADD) {
74948ccc43eSBrett Creeley struct virtchnl_vlan_supported_caps *filtering_support =
75048ccc43eSBrett Creeley &adapter->vlan_v2_caps.filtering.filtering_support;
75148ccc43eSBrett Creeley struct virtchnl_vlan *vlan;
75248ccc43eSBrett Creeley
753968996c0SPrzemyslaw Patynowski if (i == count)
754968996c0SPrzemyslaw Patynowski break;
755968996c0SPrzemyslaw Patynowski
75648ccc43eSBrett Creeley /* give priority over outer if it's enabled */
75748ccc43eSBrett Creeley if (filtering_support->outer)
75848ccc43eSBrett Creeley vlan = &vvfl_v2->filters[i].outer;
75948ccc43eSBrett Creeley else
76048ccc43eSBrett Creeley vlan = &vvfl_v2->filters[i].inner;
76148ccc43eSBrett Creeley
76248ccc43eSBrett Creeley vlan->tci = f->vlan.vid;
76348ccc43eSBrett Creeley vlan->tpid = f->vlan.tpid;
76448ccc43eSBrett Creeley
76548ccc43eSBrett Creeley i++;
7660c0da0e9SAhmed Zaki f->state = IAVF_VLAN_IS_NEW;
76748ccc43eSBrett Creeley }
76848ccc43eSBrett Creeley }
76948ccc43eSBrett Creeley
77048ccc43eSBrett Creeley if (!more)
77148ccc43eSBrett Creeley adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
77248ccc43eSBrett Creeley
77348ccc43eSBrett Creeley spin_unlock_bh(&adapter->mac_vlan_list_lock);
77448ccc43eSBrett Creeley
77548ccc43eSBrett Creeley iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN_V2,
77648ccc43eSBrett Creeley (u8 *)vvfl_v2, len);
77748ccc43eSBrett Creeley kfree(vvfl_v2);
77848ccc43eSBrett Creeley }
7795ec8b7d1SJesse Brandeburg }
7805ec8b7d1SJesse Brandeburg
7815ec8b7d1SJesse Brandeburg /**
7825ec8b7d1SJesse Brandeburg * iavf_del_vlans
7835ec8b7d1SJesse Brandeburg * @adapter: adapter structure
7845ec8b7d1SJesse Brandeburg *
7855ec8b7d1SJesse Brandeburg * Request that the PF remove one or more VLAN filters from our VSI.
7865ec8b7d1SJesse Brandeburg **/
iavf_del_vlans(struct iavf_adapter * adapter)7875ec8b7d1SJesse Brandeburg void iavf_del_vlans(struct iavf_adapter *adapter)
7885ec8b7d1SJesse Brandeburg {
7895ec8b7d1SJesse Brandeburg struct iavf_vlan_filter *f, *ftmp;
7905ec8b7d1SJesse Brandeburg int len, i = 0, count = 0;
7915ec8b7d1SJesse Brandeburg bool more = false;
7925ec8b7d1SJesse Brandeburg
7935ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
7945ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
7955ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot remove VLANs, command %d pending\n",
7965ec8b7d1SJesse Brandeburg adapter->current_op);
7975ec8b7d1SJesse Brandeburg return;
7985ec8b7d1SJesse Brandeburg }
7995ec8b7d1SJesse Brandeburg
8005ec8b7d1SJesse Brandeburg spin_lock_bh(&adapter->mac_vlan_list_lock);
8015ec8b7d1SJesse Brandeburg
8025951a2b9SBrett Creeley list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
8035951a2b9SBrett Creeley /* since VLAN capabilities are not allowed, we dont want to send
8045951a2b9SBrett Creeley * a VLAN delete request because it will most likely fail and
8055951a2b9SBrett Creeley * create unnecessary errors/noise, so just free the VLAN
8065951a2b9SBrett Creeley * filters marked for removal to enable bailing out before
8075951a2b9SBrett Creeley * sending a virtchnl message
8085951a2b9SBrett Creeley */
8090c0da0e9SAhmed Zaki if (f->state == IAVF_VLAN_REMOVE &&
8100c0da0e9SAhmed Zaki !VLAN_FILTERING_ALLOWED(adapter)) {
8115951a2b9SBrett Creeley list_del(&f->list);
8125951a2b9SBrett Creeley kfree(f);
8139c85b7faSAhmed Zaki adapter->num_vlan_filters--;
8149c85b7faSAhmed Zaki } else if (f->state == IAVF_VLAN_DISABLE &&
8159c85b7faSAhmed Zaki !VLAN_FILTERING_ALLOWED(adapter)) {
8169c85b7faSAhmed Zaki f->state = IAVF_VLAN_INACTIVE;
8179c85b7faSAhmed Zaki } else if (f->state == IAVF_VLAN_REMOVE ||
8189c85b7faSAhmed Zaki f->state == IAVF_VLAN_DISABLE) {
8195ec8b7d1SJesse Brandeburg count++;
8205ec8b7d1SJesse Brandeburg }
8215951a2b9SBrett Creeley }
82248ccc43eSBrett Creeley if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
8235ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
8245ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
8255ec8b7d1SJesse Brandeburg return;
8265ec8b7d1SJesse Brandeburg }
82748ccc43eSBrett Creeley
82848ccc43eSBrett Creeley if (VLAN_ALLOWED(adapter)) {
82948ccc43eSBrett Creeley struct virtchnl_vlan_filter_list *vvfl;
83048ccc43eSBrett Creeley
8315ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DEL_VLAN;
8325ec8b7d1SJesse Brandeburg
8335e7f59faSAlexander Lobakin len = virtchnl_struct_size(vvfl, vlan_id, count);
8345ec8b7d1SJesse Brandeburg if (len > IAVF_MAX_AQ_BUF_SIZE) {
8355ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev, "Too many delete VLAN changes in one request\n");
8365e7f59faSAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
8375e7f59faSAlexander Lobakin len = virtchnl_struct_size(vvfl, vlan_id,
8385e7f59faSAlexander Lobakin --count);
8395ec8b7d1SJesse Brandeburg more = true;
8405ec8b7d1SJesse Brandeburg }
8415ec8b7d1SJesse Brandeburg vvfl = kzalloc(len, GFP_ATOMIC);
8425ec8b7d1SJesse Brandeburg if (!vvfl) {
8435ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
8445ec8b7d1SJesse Brandeburg return;
8455ec8b7d1SJesse Brandeburg }
8465ec8b7d1SJesse Brandeburg
8475ec8b7d1SJesse Brandeburg vvfl->vsi_id = adapter->vsi_res->vsi_id;
8485ec8b7d1SJesse Brandeburg vvfl->num_elements = count;
8495ec8b7d1SJesse Brandeburg list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
8509c85b7faSAhmed Zaki if (f->state == IAVF_VLAN_DISABLE) {
85148ccc43eSBrett Creeley vvfl->vlan_id[i] = f->vlan.vid;
8529c85b7faSAhmed Zaki f->state = IAVF_VLAN_INACTIVE;
8535ec8b7d1SJesse Brandeburg i++;
8549c85b7faSAhmed Zaki if (i == count)
8559c85b7faSAhmed Zaki break;
8569c85b7faSAhmed Zaki } else if (f->state == IAVF_VLAN_REMOVE) {
8579c85b7faSAhmed Zaki vvfl->vlan_id[i] = f->vlan.vid;
8585ec8b7d1SJesse Brandeburg list_del(&f->list);
8595ec8b7d1SJesse Brandeburg kfree(f);
8609c85b7faSAhmed Zaki adapter->num_vlan_filters--;
8619c85b7faSAhmed Zaki i++;
8625ec8b7d1SJesse Brandeburg if (i == count)
8635ec8b7d1SJesse Brandeburg break;
8645ec8b7d1SJesse Brandeburg }
8655ec8b7d1SJesse Brandeburg }
86648ccc43eSBrett Creeley
8675ec8b7d1SJesse Brandeburg if (!more)
8685ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
8695ec8b7d1SJesse Brandeburg
8705ec8b7d1SJesse Brandeburg spin_unlock_bh(&adapter->mac_vlan_list_lock);
8715ec8b7d1SJesse Brandeburg
8725ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
8735ec8b7d1SJesse Brandeburg kfree(vvfl);
87448ccc43eSBrett Creeley } else {
87548ccc43eSBrett Creeley struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
87648ccc43eSBrett Creeley
87748ccc43eSBrett Creeley adapter->current_op = VIRTCHNL_OP_DEL_VLAN_V2;
87848ccc43eSBrett Creeley
879b0654e64SAlexander Lobakin len = virtchnl_struct_size(vvfl_v2, filters, count);
88048ccc43eSBrett Creeley if (len > IAVF_MAX_AQ_BUF_SIZE) {
88148ccc43eSBrett Creeley dev_warn(&adapter->pdev->dev, "Too many add VLAN changes in one request\n");
882b0654e64SAlexander Lobakin while (len > IAVF_MAX_AQ_BUF_SIZE)
883b0654e64SAlexander Lobakin len = virtchnl_struct_size(vvfl_v2, filters,
884b0654e64SAlexander Lobakin --count);
88548ccc43eSBrett Creeley more = true;
88648ccc43eSBrett Creeley }
88748ccc43eSBrett Creeley
88848ccc43eSBrett Creeley vvfl_v2 = kzalloc(len, GFP_ATOMIC);
88948ccc43eSBrett Creeley if (!vvfl_v2) {
89048ccc43eSBrett Creeley spin_unlock_bh(&adapter->mac_vlan_list_lock);
89148ccc43eSBrett Creeley return;
89248ccc43eSBrett Creeley }
89348ccc43eSBrett Creeley
89448ccc43eSBrett Creeley vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
89548ccc43eSBrett Creeley vvfl_v2->num_elements = count;
89648ccc43eSBrett Creeley list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
8979c85b7faSAhmed Zaki if (f->state == IAVF_VLAN_DISABLE ||
8989c85b7faSAhmed Zaki f->state == IAVF_VLAN_REMOVE) {
89948ccc43eSBrett Creeley struct virtchnl_vlan_supported_caps *filtering_support =
90048ccc43eSBrett Creeley &adapter->vlan_v2_caps.filtering.filtering_support;
90148ccc43eSBrett Creeley struct virtchnl_vlan *vlan;
90248ccc43eSBrett Creeley
90348ccc43eSBrett Creeley /* give priority over outer if it's enabled */
90448ccc43eSBrett Creeley if (filtering_support->outer)
90548ccc43eSBrett Creeley vlan = &vvfl_v2->filters[i].outer;
90648ccc43eSBrett Creeley else
90748ccc43eSBrett Creeley vlan = &vvfl_v2->filters[i].inner;
90848ccc43eSBrett Creeley
90948ccc43eSBrett Creeley vlan->tci = f->vlan.vid;
91048ccc43eSBrett Creeley vlan->tpid = f->vlan.tpid;
91148ccc43eSBrett Creeley
9129c85b7faSAhmed Zaki if (f->state == IAVF_VLAN_DISABLE) {
9139c85b7faSAhmed Zaki f->state = IAVF_VLAN_INACTIVE;
9149c85b7faSAhmed Zaki } else {
91548ccc43eSBrett Creeley list_del(&f->list);
91648ccc43eSBrett Creeley kfree(f);
9179c85b7faSAhmed Zaki adapter->num_vlan_filters--;
9189c85b7faSAhmed Zaki }
91948ccc43eSBrett Creeley i++;
92048ccc43eSBrett Creeley if (i == count)
92148ccc43eSBrett Creeley break;
92248ccc43eSBrett Creeley }
92348ccc43eSBrett Creeley }
92448ccc43eSBrett Creeley
92548ccc43eSBrett Creeley if (!more)
92648ccc43eSBrett Creeley adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
92748ccc43eSBrett Creeley
92848ccc43eSBrett Creeley spin_unlock_bh(&adapter->mac_vlan_list_lock);
92948ccc43eSBrett Creeley
93048ccc43eSBrett Creeley iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_VLAN_V2,
93148ccc43eSBrett Creeley (u8 *)vvfl_v2, len);
93248ccc43eSBrett Creeley kfree(vvfl_v2);
93348ccc43eSBrett Creeley }
9345ec8b7d1SJesse Brandeburg }
9355ec8b7d1SJesse Brandeburg
9365ec8b7d1SJesse Brandeburg /**
9375ec8b7d1SJesse Brandeburg * iavf_set_promiscuous
9385ec8b7d1SJesse Brandeburg * @adapter: adapter structure
9395ec8b7d1SJesse Brandeburg *
9405ec8b7d1SJesse Brandeburg * Request that the PF enable promiscuous mode for our VSI.
9415ec8b7d1SJesse Brandeburg **/
iavf_set_promiscuous(struct iavf_adapter * adapter)9427e85cf09SBrett Creeley void iavf_set_promiscuous(struct iavf_adapter *adapter)
9435ec8b7d1SJesse Brandeburg {
9447e85cf09SBrett Creeley struct net_device *netdev = adapter->netdev;
9455ec8b7d1SJesse Brandeburg struct virtchnl_promisc_info vpi;
9467e85cf09SBrett Creeley unsigned int flags;
9475ec8b7d1SJesse Brandeburg
9485ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
9495ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
9505ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot set promiscuous mode, command %d pending\n",
9515ec8b7d1SJesse Brandeburg adapter->current_op);
9525ec8b7d1SJesse Brandeburg return;
9535ec8b7d1SJesse Brandeburg }
9545ec8b7d1SJesse Brandeburg
9557e85cf09SBrett Creeley /* prevent changes to promiscuous flags */
9567e85cf09SBrett Creeley spin_lock_bh(&adapter->current_netdev_promisc_flags_lock);
9577e85cf09SBrett Creeley
9587e85cf09SBrett Creeley /* sanity check to prevent duplicate AQ calls */
9597e85cf09SBrett Creeley if (!iavf_promiscuous_mode_changed(adapter)) {
9607e85cf09SBrett Creeley adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE;
9617e85cf09SBrett Creeley dev_dbg(&adapter->pdev->dev, "No change in promiscuous mode\n");
9627e85cf09SBrett Creeley /* allow changes to promiscuous flags */
9637e85cf09SBrett Creeley spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock);
9647e85cf09SBrett Creeley return;
9657e85cf09SBrett Creeley }
9667e85cf09SBrett Creeley
9677e85cf09SBrett Creeley /* there are 2 bits, but only 3 states */
9687e85cf09SBrett Creeley if (!(netdev->flags & IFF_PROMISC) &&
9697e85cf09SBrett Creeley netdev->flags & IFF_ALLMULTI) {
9707e85cf09SBrett Creeley /* State 1 - only multicast promiscuous mode enabled
9717e85cf09SBrett Creeley * - !IFF_PROMISC && IFF_ALLMULTI
9727e85cf09SBrett Creeley */
9737e85cf09SBrett Creeley flags = FLAG_VF_MULTICAST_PROMISC;
9747e85cf09SBrett Creeley adapter->current_netdev_promisc_flags |= IFF_ALLMULTI;
9757e85cf09SBrett Creeley adapter->current_netdev_promisc_flags &= ~IFF_PROMISC;
9767e85cf09SBrett Creeley dev_info(&adapter->pdev->dev, "Entering multicast promiscuous mode\n");
9777e85cf09SBrett Creeley } else if (!(netdev->flags & IFF_PROMISC) &&
9787e85cf09SBrett Creeley !(netdev->flags & IFF_ALLMULTI)) {
9797e85cf09SBrett Creeley /* State 2 - unicast/multicast promiscuous mode disabled
9807e85cf09SBrett Creeley * - !IFF_PROMISC && !IFF_ALLMULTI
9817e85cf09SBrett Creeley */
9827e85cf09SBrett Creeley flags = 0;
9837e85cf09SBrett Creeley adapter->current_netdev_promisc_flags &=
9847e85cf09SBrett Creeley ~(IFF_PROMISC | IFF_ALLMULTI);
9857e85cf09SBrett Creeley dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n");
9867e85cf09SBrett Creeley } else {
9877e85cf09SBrett Creeley /* State 3 - unicast/multicast promiscuous mode enabled
9887e85cf09SBrett Creeley * - IFF_PROMISC && IFF_ALLMULTI
9897e85cf09SBrett Creeley * - IFF_PROMISC && !IFF_ALLMULTI
9907e85cf09SBrett Creeley */
9917e85cf09SBrett Creeley flags = FLAG_VF_UNICAST_PROMISC | FLAG_VF_MULTICAST_PROMISC;
9927e85cf09SBrett Creeley adapter->current_netdev_promisc_flags |= IFF_PROMISC;
9937e85cf09SBrett Creeley if (netdev->flags & IFF_ALLMULTI)
9947e85cf09SBrett Creeley adapter->current_netdev_promisc_flags |= IFF_ALLMULTI;
9957e85cf09SBrett Creeley else
9967e85cf09SBrett Creeley adapter->current_netdev_promisc_flags &= ~IFF_ALLMULTI;
9977e85cf09SBrett Creeley
9985ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n");
9995ec8b7d1SJesse Brandeburg }
10005ec8b7d1SJesse Brandeburg
10017e85cf09SBrett Creeley adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE;
10025ec8b7d1SJesse Brandeburg
10037e85cf09SBrett Creeley /* allow changes to promiscuous flags */
10047e85cf09SBrett Creeley spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock);
1005f1db020bSGrzegorz Szczurek
10065ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
10075ec8b7d1SJesse Brandeburg vpi.vsi_id = adapter->vsi_res->vsi_id;
10085ec8b7d1SJesse Brandeburg vpi.flags = flags;
10095ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
10105ec8b7d1SJesse Brandeburg (u8 *)&vpi, sizeof(vpi));
10115ec8b7d1SJesse Brandeburg }
10125ec8b7d1SJesse Brandeburg
10135ec8b7d1SJesse Brandeburg /**
10145ec8b7d1SJesse Brandeburg * iavf_request_stats
10155ec8b7d1SJesse Brandeburg * @adapter: adapter structure
10165ec8b7d1SJesse Brandeburg *
10175ec8b7d1SJesse Brandeburg * Request VSI statistics from PF.
10185ec8b7d1SJesse Brandeburg **/
iavf_request_stats(struct iavf_adapter * adapter)10195ec8b7d1SJesse Brandeburg void iavf_request_stats(struct iavf_adapter *adapter)
10205ec8b7d1SJesse Brandeburg {
10215ec8b7d1SJesse Brandeburg struct virtchnl_queue_select vqs;
10225ec8b7d1SJesse Brandeburg
10235ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
10245ec8b7d1SJesse Brandeburg /* no error message, this isn't crucial */
10255ec8b7d1SJesse Brandeburg return;
10265ec8b7d1SJesse Brandeburg }
10273b5bdd18SJedrzej Jagielski
10283b5bdd18SJedrzej Jagielski adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_STATS;
10295ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_GET_STATS;
10305ec8b7d1SJesse Brandeburg vqs.vsi_id = adapter->vsi_res->vsi_id;
10315ec8b7d1SJesse Brandeburg /* queue maps are ignored for this message - only the vsi is used */
10325ec8b7d1SJesse Brandeburg if (iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_STATS, (u8 *)&vqs,
10335ec8b7d1SJesse Brandeburg sizeof(vqs)))
10345ec8b7d1SJesse Brandeburg /* if the request failed, don't lock out others */
10355ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_UNKNOWN;
10365ec8b7d1SJesse Brandeburg }
10375ec8b7d1SJesse Brandeburg
10385ec8b7d1SJesse Brandeburg /**
10395ec8b7d1SJesse Brandeburg * iavf_get_hena
10405ec8b7d1SJesse Brandeburg * @adapter: adapter structure
10415ec8b7d1SJesse Brandeburg *
10425ec8b7d1SJesse Brandeburg * Request hash enable capabilities from PF
10435ec8b7d1SJesse Brandeburg **/
iavf_get_hena(struct iavf_adapter * adapter)10445ec8b7d1SJesse Brandeburg void iavf_get_hena(struct iavf_adapter *adapter)
10455ec8b7d1SJesse Brandeburg {
10465ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
10475ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
10485ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot get RSS hash capabilities, command %d pending\n",
10495ec8b7d1SJesse Brandeburg adapter->current_op);
10505ec8b7d1SJesse Brandeburg return;
10515ec8b7d1SJesse Brandeburg }
10525ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_GET_RSS_HENA_CAPS;
10535ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_GET_HENA;
10545ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_RSS_HENA_CAPS, NULL, 0);
10555ec8b7d1SJesse Brandeburg }
10565ec8b7d1SJesse Brandeburg
10575ec8b7d1SJesse Brandeburg /**
10585ec8b7d1SJesse Brandeburg * iavf_set_hena
10595ec8b7d1SJesse Brandeburg * @adapter: adapter structure
10605ec8b7d1SJesse Brandeburg *
10615ec8b7d1SJesse Brandeburg * Request the PF to set our RSS hash capabilities
10625ec8b7d1SJesse Brandeburg **/
iavf_set_hena(struct iavf_adapter * adapter)10635ec8b7d1SJesse Brandeburg void iavf_set_hena(struct iavf_adapter *adapter)
10645ec8b7d1SJesse Brandeburg {
10655ec8b7d1SJesse Brandeburg struct virtchnl_rss_hena vrh;
10665ec8b7d1SJesse Brandeburg
10675ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
10685ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
10695ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot set RSS hash enable, command %d pending\n",
10705ec8b7d1SJesse Brandeburg adapter->current_op);
10715ec8b7d1SJesse Brandeburg return;
10725ec8b7d1SJesse Brandeburg }
10735ec8b7d1SJesse Brandeburg vrh.hena = adapter->hena;
10745ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_SET_RSS_HENA;
10755ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_SET_HENA;
10765ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_SET_RSS_HENA, (u8 *)&vrh,
10775ec8b7d1SJesse Brandeburg sizeof(vrh));
10785ec8b7d1SJesse Brandeburg }
10795ec8b7d1SJesse Brandeburg
10805ec8b7d1SJesse Brandeburg /**
10815ec8b7d1SJesse Brandeburg * iavf_set_rss_key
10825ec8b7d1SJesse Brandeburg * @adapter: adapter structure
10835ec8b7d1SJesse Brandeburg *
10845ec8b7d1SJesse Brandeburg * Request the PF to set our RSS hash key
10855ec8b7d1SJesse Brandeburg **/
iavf_set_rss_key(struct iavf_adapter * adapter)10865ec8b7d1SJesse Brandeburg void iavf_set_rss_key(struct iavf_adapter *adapter)
10875ec8b7d1SJesse Brandeburg {
10885ec8b7d1SJesse Brandeburg struct virtchnl_rss_key *vrk;
10895ec8b7d1SJesse Brandeburg int len;
10905ec8b7d1SJesse Brandeburg
10915ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
10925ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
10935ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot set RSS key, command %d pending\n",
10945ec8b7d1SJesse Brandeburg adapter->current_op);
10955ec8b7d1SJesse Brandeburg return;
10965ec8b7d1SJesse Brandeburg }
1097dd2e84bbSAlexander Lobakin len = virtchnl_struct_size(vrk, key, adapter->rss_key_size);
10985ec8b7d1SJesse Brandeburg vrk = kzalloc(len, GFP_KERNEL);
10995ec8b7d1SJesse Brandeburg if (!vrk)
11005ec8b7d1SJesse Brandeburg return;
11015ec8b7d1SJesse Brandeburg vrk->vsi_id = adapter->vsi.id;
11025ec8b7d1SJesse Brandeburg vrk->key_len = adapter->rss_key_size;
11035ec8b7d1SJesse Brandeburg memcpy(vrk->key, adapter->rss_key, adapter->rss_key_size);
11045ec8b7d1SJesse Brandeburg
11055ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_CONFIG_RSS_KEY;
11065ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_SET_RSS_KEY;
11075ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_RSS_KEY, (u8 *)vrk, len);
11085ec8b7d1SJesse Brandeburg kfree(vrk);
11095ec8b7d1SJesse Brandeburg }
11105ec8b7d1SJesse Brandeburg
11115ec8b7d1SJesse Brandeburg /**
11125ec8b7d1SJesse Brandeburg * iavf_set_rss_lut
11135ec8b7d1SJesse Brandeburg * @adapter: adapter structure
11145ec8b7d1SJesse Brandeburg *
11155ec8b7d1SJesse Brandeburg * Request the PF to set our RSS lookup table
11165ec8b7d1SJesse Brandeburg **/
iavf_set_rss_lut(struct iavf_adapter * adapter)11175ec8b7d1SJesse Brandeburg void iavf_set_rss_lut(struct iavf_adapter *adapter)
11185ec8b7d1SJesse Brandeburg {
11195ec8b7d1SJesse Brandeburg struct virtchnl_rss_lut *vrl;
11205ec8b7d1SJesse Brandeburg int len;
11215ec8b7d1SJesse Brandeburg
11225ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
11235ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
11245ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot set RSS LUT, command %d pending\n",
11255ec8b7d1SJesse Brandeburg adapter->current_op);
11265ec8b7d1SJesse Brandeburg return;
11275ec8b7d1SJesse Brandeburg }
1128dd2e84bbSAlexander Lobakin len = virtchnl_struct_size(vrl, lut, adapter->rss_lut_size);
11295ec8b7d1SJesse Brandeburg vrl = kzalloc(len, GFP_KERNEL);
11305ec8b7d1SJesse Brandeburg if (!vrl)
11315ec8b7d1SJesse Brandeburg return;
11325ec8b7d1SJesse Brandeburg vrl->vsi_id = adapter->vsi.id;
11335ec8b7d1SJesse Brandeburg vrl->lut_entries = adapter->rss_lut_size;
11345ec8b7d1SJesse Brandeburg memcpy(vrl->lut, adapter->rss_lut, adapter->rss_lut_size);
11355ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_CONFIG_RSS_LUT;
11365ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_SET_RSS_LUT;
11375ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_RSS_LUT, (u8 *)vrl, len);
11385ec8b7d1SJesse Brandeburg kfree(vrl);
11395ec8b7d1SJesse Brandeburg }
11405ec8b7d1SJesse Brandeburg
11415ec8b7d1SJesse Brandeburg /**
11425ec8b7d1SJesse Brandeburg * iavf_enable_vlan_stripping
11435ec8b7d1SJesse Brandeburg * @adapter: adapter structure
11445ec8b7d1SJesse Brandeburg *
11455ec8b7d1SJesse Brandeburg * Request VLAN header stripping to be enabled
11465ec8b7d1SJesse Brandeburg **/
iavf_enable_vlan_stripping(struct iavf_adapter * adapter)11475ec8b7d1SJesse Brandeburg void iavf_enable_vlan_stripping(struct iavf_adapter *adapter)
11485ec8b7d1SJesse Brandeburg {
11495ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
11505ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
11515ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot enable stripping, command %d pending\n",
11525ec8b7d1SJesse Brandeburg adapter->current_op);
11535ec8b7d1SJesse Brandeburg return;
11545ec8b7d1SJesse Brandeburg }
11555ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
11565ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING;
11575ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, NULL, 0);
11585ec8b7d1SJesse Brandeburg }
11595ec8b7d1SJesse Brandeburg
11605ec8b7d1SJesse Brandeburg /**
11615ec8b7d1SJesse Brandeburg * iavf_disable_vlan_stripping
11625ec8b7d1SJesse Brandeburg * @adapter: adapter structure
11635ec8b7d1SJesse Brandeburg *
11645ec8b7d1SJesse Brandeburg * Request VLAN header stripping to be disabled
11655ec8b7d1SJesse Brandeburg **/
iavf_disable_vlan_stripping(struct iavf_adapter * adapter)11665ec8b7d1SJesse Brandeburg void iavf_disable_vlan_stripping(struct iavf_adapter *adapter)
11675ec8b7d1SJesse Brandeburg {
11685ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
11695ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
11705ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot disable stripping, command %d pending\n",
11715ec8b7d1SJesse Brandeburg adapter->current_op);
11725ec8b7d1SJesse Brandeburg return;
11735ec8b7d1SJesse Brandeburg }
11745ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
11755ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING;
11765ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, NULL, 0);
11775ec8b7d1SJesse Brandeburg }
11785ec8b7d1SJesse Brandeburg
11798afadd1cSBrett Creeley /**
11808afadd1cSBrett Creeley * iavf_tpid_to_vc_ethertype - transform from VLAN TPID to virtchnl ethertype
11818afadd1cSBrett Creeley * @tpid: VLAN TPID (i.e. 0x8100, 0x88a8, etc.)
11828afadd1cSBrett Creeley */
iavf_tpid_to_vc_ethertype(u16 tpid)11838afadd1cSBrett Creeley static u32 iavf_tpid_to_vc_ethertype(u16 tpid)
11848afadd1cSBrett Creeley {
11858afadd1cSBrett Creeley switch (tpid) {
11868afadd1cSBrett Creeley case ETH_P_8021Q:
11878afadd1cSBrett Creeley return VIRTCHNL_VLAN_ETHERTYPE_8100;
11888afadd1cSBrett Creeley case ETH_P_8021AD:
11898afadd1cSBrett Creeley return VIRTCHNL_VLAN_ETHERTYPE_88A8;
11908afadd1cSBrett Creeley }
11918afadd1cSBrett Creeley
11928afadd1cSBrett Creeley return 0;
11938afadd1cSBrett Creeley }
11948afadd1cSBrett Creeley
11958afadd1cSBrett Creeley /**
11968afadd1cSBrett Creeley * iavf_set_vc_offload_ethertype - set virtchnl ethertype for offload message
11978afadd1cSBrett Creeley * @adapter: adapter structure
11988afadd1cSBrett Creeley * @msg: message structure used for updating offloads over virtchnl to update
11998afadd1cSBrett Creeley * @tpid: VLAN TPID (i.e. 0x8100, 0x88a8, etc.)
12008afadd1cSBrett Creeley * @offload_op: opcode used to determine which support structure to check
12018afadd1cSBrett Creeley */
12028afadd1cSBrett Creeley static int
iavf_set_vc_offload_ethertype(struct iavf_adapter * adapter,struct virtchnl_vlan_setting * msg,u16 tpid,enum virtchnl_ops offload_op)12038afadd1cSBrett Creeley iavf_set_vc_offload_ethertype(struct iavf_adapter *adapter,
12048afadd1cSBrett Creeley struct virtchnl_vlan_setting *msg, u16 tpid,
12058afadd1cSBrett Creeley enum virtchnl_ops offload_op)
12068afadd1cSBrett Creeley {
12078afadd1cSBrett Creeley struct virtchnl_vlan_supported_caps *offload_support;
12088afadd1cSBrett Creeley u16 vc_ethertype = iavf_tpid_to_vc_ethertype(tpid);
12098afadd1cSBrett Creeley
12108afadd1cSBrett Creeley /* reference the correct offload support structure */
12118afadd1cSBrett Creeley switch (offload_op) {
12128afadd1cSBrett Creeley case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2:
12138afadd1cSBrett Creeley case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2:
12148afadd1cSBrett Creeley offload_support =
12158afadd1cSBrett Creeley &adapter->vlan_v2_caps.offloads.stripping_support;
12168afadd1cSBrett Creeley break;
12178afadd1cSBrett Creeley case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2:
12188afadd1cSBrett Creeley case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2:
12198afadd1cSBrett Creeley offload_support =
12208afadd1cSBrett Creeley &adapter->vlan_v2_caps.offloads.insertion_support;
12218afadd1cSBrett Creeley break;
12228afadd1cSBrett Creeley default:
12238afadd1cSBrett Creeley dev_err(&adapter->pdev->dev, "Invalid opcode %d for setting virtchnl ethertype to enable/disable VLAN offloads\n",
12248afadd1cSBrett Creeley offload_op);
12258afadd1cSBrett Creeley return -EINVAL;
12268afadd1cSBrett Creeley }
12278afadd1cSBrett Creeley
12288afadd1cSBrett Creeley /* make sure ethertype is supported */
12298afadd1cSBrett Creeley if (offload_support->outer & vc_ethertype &&
12308afadd1cSBrett Creeley offload_support->outer & VIRTCHNL_VLAN_TOGGLE) {
12318afadd1cSBrett Creeley msg->outer_ethertype_setting = vc_ethertype;
12328afadd1cSBrett Creeley } else if (offload_support->inner & vc_ethertype &&
12338afadd1cSBrett Creeley offload_support->inner & VIRTCHNL_VLAN_TOGGLE) {
12348afadd1cSBrett Creeley msg->inner_ethertype_setting = vc_ethertype;
12358afadd1cSBrett Creeley } else {
12368afadd1cSBrett Creeley dev_dbg(&adapter->pdev->dev, "opcode %d unsupported for VLAN TPID 0x%04x\n",
12378afadd1cSBrett Creeley offload_op, tpid);
12388afadd1cSBrett Creeley return -EINVAL;
12398afadd1cSBrett Creeley }
12408afadd1cSBrett Creeley
12418afadd1cSBrett Creeley return 0;
12428afadd1cSBrett Creeley }
12438afadd1cSBrett Creeley
12448afadd1cSBrett Creeley /**
12458afadd1cSBrett Creeley * iavf_clear_offload_v2_aq_required - clear AQ required bit for offload request
12468afadd1cSBrett Creeley * @adapter: adapter structure
12478afadd1cSBrett Creeley * @tpid: VLAN TPID
12488afadd1cSBrett Creeley * @offload_op: opcode used to determine which AQ required bit to clear
12498afadd1cSBrett Creeley */
12508afadd1cSBrett Creeley static void
iavf_clear_offload_v2_aq_required(struct iavf_adapter * adapter,u16 tpid,enum virtchnl_ops offload_op)12518afadd1cSBrett Creeley iavf_clear_offload_v2_aq_required(struct iavf_adapter *adapter, u16 tpid,
12528afadd1cSBrett Creeley enum virtchnl_ops offload_op)
12538afadd1cSBrett Creeley {
12548afadd1cSBrett Creeley switch (offload_op) {
12558afadd1cSBrett Creeley case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2:
12568afadd1cSBrett Creeley if (tpid == ETH_P_8021Q)
12578afadd1cSBrett Creeley adapter->aq_required &=
12588afadd1cSBrett Creeley ~IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING;
12598afadd1cSBrett Creeley else if (tpid == ETH_P_8021AD)
12608afadd1cSBrett Creeley adapter->aq_required &=
12618afadd1cSBrett Creeley ~IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING;
12628afadd1cSBrett Creeley break;
12638afadd1cSBrett Creeley case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2:
12648afadd1cSBrett Creeley if (tpid == ETH_P_8021Q)
12658afadd1cSBrett Creeley adapter->aq_required &=
12668afadd1cSBrett Creeley ~IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING;
12678afadd1cSBrett Creeley else if (tpid == ETH_P_8021AD)
12688afadd1cSBrett Creeley adapter->aq_required &=
12698afadd1cSBrett Creeley ~IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING;
12708afadd1cSBrett Creeley break;
12718afadd1cSBrett Creeley case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2:
12728afadd1cSBrett Creeley if (tpid == ETH_P_8021Q)
12738afadd1cSBrett Creeley adapter->aq_required &=
12748afadd1cSBrett Creeley ~IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION;
12758afadd1cSBrett Creeley else if (tpid == ETH_P_8021AD)
12768afadd1cSBrett Creeley adapter->aq_required &=
12778afadd1cSBrett Creeley ~IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION;
12788afadd1cSBrett Creeley break;
12798afadd1cSBrett Creeley case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2:
12808afadd1cSBrett Creeley if (tpid == ETH_P_8021Q)
12818afadd1cSBrett Creeley adapter->aq_required &=
12828afadd1cSBrett Creeley ~IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION;
12838afadd1cSBrett Creeley else if (tpid == ETH_P_8021AD)
12848afadd1cSBrett Creeley adapter->aq_required &=
12858afadd1cSBrett Creeley ~IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION;
12868afadd1cSBrett Creeley break;
12878afadd1cSBrett Creeley default:
12888afadd1cSBrett Creeley dev_err(&adapter->pdev->dev, "Unsupported opcode %d specified for clearing aq_required bits for VIRTCHNL_VF_OFFLOAD_VLAN_V2 offload request\n",
12898afadd1cSBrett Creeley offload_op);
12908afadd1cSBrett Creeley }
12918afadd1cSBrett Creeley }
12928afadd1cSBrett Creeley
12938afadd1cSBrett Creeley /**
12948afadd1cSBrett Creeley * iavf_send_vlan_offload_v2 - send offload enable/disable over virtchnl
12958afadd1cSBrett Creeley * @adapter: adapter structure
12968afadd1cSBrett Creeley * @tpid: VLAN TPID used for the command (i.e. 0x8100 or 0x88a8)
12978afadd1cSBrett Creeley * @offload_op: offload_op used to make the request over virtchnl
12988afadd1cSBrett Creeley */
12998afadd1cSBrett Creeley static void
iavf_send_vlan_offload_v2(struct iavf_adapter * adapter,u16 tpid,enum virtchnl_ops offload_op)13008afadd1cSBrett Creeley iavf_send_vlan_offload_v2(struct iavf_adapter *adapter, u16 tpid,
13018afadd1cSBrett Creeley enum virtchnl_ops offload_op)
13028afadd1cSBrett Creeley {
13038afadd1cSBrett Creeley struct virtchnl_vlan_setting *msg;
13048afadd1cSBrett Creeley int len = sizeof(*msg);
13058afadd1cSBrett Creeley
13068afadd1cSBrett Creeley if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
13078afadd1cSBrett Creeley /* bail because we already have a command pending */
13088afadd1cSBrett Creeley dev_err(&adapter->pdev->dev, "Cannot send %d, command %d pending\n",
13098afadd1cSBrett Creeley offload_op, adapter->current_op);
13108afadd1cSBrett Creeley return;
13118afadd1cSBrett Creeley }
13128afadd1cSBrett Creeley
13138afadd1cSBrett Creeley adapter->current_op = offload_op;
13148afadd1cSBrett Creeley
13158afadd1cSBrett Creeley msg = kzalloc(len, GFP_KERNEL);
13168afadd1cSBrett Creeley if (!msg)
13178afadd1cSBrett Creeley return;
13188afadd1cSBrett Creeley
13198afadd1cSBrett Creeley msg->vport_id = adapter->vsi_res->vsi_id;
13208afadd1cSBrett Creeley
13218afadd1cSBrett Creeley /* always clear to prevent unsupported and endless requests */
13228afadd1cSBrett Creeley iavf_clear_offload_v2_aq_required(adapter, tpid, offload_op);
13238afadd1cSBrett Creeley
13248afadd1cSBrett Creeley /* only send valid offload requests */
13258afadd1cSBrett Creeley if (!iavf_set_vc_offload_ethertype(adapter, msg, tpid, offload_op))
13268afadd1cSBrett Creeley iavf_send_pf_msg(adapter, offload_op, (u8 *)msg, len);
13278afadd1cSBrett Creeley else
13288afadd1cSBrett Creeley adapter->current_op = VIRTCHNL_OP_UNKNOWN;
13298afadd1cSBrett Creeley
13308afadd1cSBrett Creeley kfree(msg);
13318afadd1cSBrett Creeley }
13328afadd1cSBrett Creeley
13338afadd1cSBrett Creeley /**
13348afadd1cSBrett Creeley * iavf_enable_vlan_stripping_v2 - enable VLAN stripping
13358afadd1cSBrett Creeley * @adapter: adapter structure
13368afadd1cSBrett Creeley * @tpid: VLAN TPID used to enable VLAN stripping
13378afadd1cSBrett Creeley */
iavf_enable_vlan_stripping_v2(struct iavf_adapter * adapter,u16 tpid)13388afadd1cSBrett Creeley void iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid)
13398afadd1cSBrett Creeley {
13408afadd1cSBrett Creeley iavf_send_vlan_offload_v2(adapter, tpid,
13418afadd1cSBrett Creeley VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2);
13428afadd1cSBrett Creeley }
13438afadd1cSBrett Creeley
13448afadd1cSBrett Creeley /**
13458afadd1cSBrett Creeley * iavf_disable_vlan_stripping_v2 - disable VLAN stripping
13468afadd1cSBrett Creeley * @adapter: adapter structure
13478afadd1cSBrett Creeley * @tpid: VLAN TPID used to disable VLAN stripping
13488afadd1cSBrett Creeley */
iavf_disable_vlan_stripping_v2(struct iavf_adapter * adapter,u16 tpid)13498afadd1cSBrett Creeley void iavf_disable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid)
13508afadd1cSBrett Creeley {
13518afadd1cSBrett Creeley iavf_send_vlan_offload_v2(adapter, tpid,
13528afadd1cSBrett Creeley VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2);
13538afadd1cSBrett Creeley }
13548afadd1cSBrett Creeley
13558afadd1cSBrett Creeley /**
13568afadd1cSBrett Creeley * iavf_enable_vlan_insertion_v2 - enable VLAN insertion
13578afadd1cSBrett Creeley * @adapter: adapter structure
13588afadd1cSBrett Creeley * @tpid: VLAN TPID used to enable VLAN insertion
13598afadd1cSBrett Creeley */
iavf_enable_vlan_insertion_v2(struct iavf_adapter * adapter,u16 tpid)13608afadd1cSBrett Creeley void iavf_enable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid)
13618afadd1cSBrett Creeley {
13628afadd1cSBrett Creeley iavf_send_vlan_offload_v2(adapter, tpid,
13638afadd1cSBrett Creeley VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2);
13648afadd1cSBrett Creeley }
13658afadd1cSBrett Creeley
13668afadd1cSBrett Creeley /**
13678afadd1cSBrett Creeley * iavf_disable_vlan_insertion_v2 - disable VLAN insertion
13688afadd1cSBrett Creeley * @adapter: adapter structure
13698afadd1cSBrett Creeley * @tpid: VLAN TPID used to disable VLAN insertion
13708afadd1cSBrett Creeley */
iavf_disable_vlan_insertion_v2(struct iavf_adapter * adapter,u16 tpid)13718afadd1cSBrett Creeley void iavf_disable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid)
13728afadd1cSBrett Creeley {
13738afadd1cSBrett Creeley iavf_send_vlan_offload_v2(adapter, tpid,
13748afadd1cSBrett Creeley VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2);
13758afadd1cSBrett Creeley }
13768afadd1cSBrett Creeley
1377e0ef26fbSBrett Creeley #define IAVF_MAX_SPEED_STRLEN 13
1378e0ef26fbSBrett Creeley
13795ec8b7d1SJesse Brandeburg /**
13805ec8b7d1SJesse Brandeburg * iavf_print_link_message - print link up or down
13815ec8b7d1SJesse Brandeburg * @adapter: adapter structure
13825ec8b7d1SJesse Brandeburg *
13835ec8b7d1SJesse Brandeburg * Log a message telling the world of our wonderous link status
13845ec8b7d1SJesse Brandeburg */
iavf_print_link_message(struct iavf_adapter * adapter)13855ec8b7d1SJesse Brandeburg static void iavf_print_link_message(struct iavf_adapter *adapter)
13865ec8b7d1SJesse Brandeburg {
13875ec8b7d1SJesse Brandeburg struct net_device *netdev = adapter->netdev;
1388e0ef26fbSBrett Creeley int link_speed_mbps;
1389e0ef26fbSBrett Creeley char *speed;
13905ec8b7d1SJesse Brandeburg
13915ec8b7d1SJesse Brandeburg if (!adapter->link_up) {
13925ec8b7d1SJesse Brandeburg netdev_info(netdev, "NIC Link is Down\n");
13935ec8b7d1SJesse Brandeburg return;
13945ec8b7d1SJesse Brandeburg }
13955ec8b7d1SJesse Brandeburg
13968a57965eSZheng Yongjun speed = kzalloc(IAVF_MAX_SPEED_STRLEN, GFP_KERNEL);
1397e0ef26fbSBrett Creeley if (!speed)
1398e0ef26fbSBrett Creeley return;
1399e0ef26fbSBrett Creeley
1400e0ef26fbSBrett Creeley if (ADV_LINK_SUPPORT(adapter)) {
1401e0ef26fbSBrett Creeley link_speed_mbps = adapter->link_speed_mbps;
1402e0ef26fbSBrett Creeley goto print_link_msg;
1403e0ef26fbSBrett Creeley }
1404e0ef26fbSBrett Creeley
14055ec8b7d1SJesse Brandeburg switch (adapter->link_speed) {
14065071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_40GB:
1407e0ef26fbSBrett Creeley link_speed_mbps = SPEED_40000;
14085ec8b7d1SJesse Brandeburg break;
14095071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_25GB:
1410e0ef26fbSBrett Creeley link_speed_mbps = SPEED_25000;
14115ec8b7d1SJesse Brandeburg break;
14125071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_20GB:
1413e0ef26fbSBrett Creeley link_speed_mbps = SPEED_20000;
14145ec8b7d1SJesse Brandeburg break;
14155071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_10GB:
1416e0ef26fbSBrett Creeley link_speed_mbps = SPEED_10000;
14175ec8b7d1SJesse Brandeburg break;
141818c012d9SBrett Creeley case VIRTCHNL_LINK_SPEED_5GB:
141918c012d9SBrett Creeley link_speed_mbps = SPEED_5000;
142018c012d9SBrett Creeley break;
142118c012d9SBrett Creeley case VIRTCHNL_LINK_SPEED_2_5GB:
142218c012d9SBrett Creeley link_speed_mbps = SPEED_2500;
142318c012d9SBrett Creeley break;
14245071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_1GB:
1425e0ef26fbSBrett Creeley link_speed_mbps = SPEED_1000;
14265ec8b7d1SJesse Brandeburg break;
14275071bda2SAleksandr Loktionov case VIRTCHNL_LINK_SPEED_100MB:
1428e0ef26fbSBrett Creeley link_speed_mbps = SPEED_100;
14295ec8b7d1SJesse Brandeburg break;
14305ec8b7d1SJesse Brandeburg default:
1431e0ef26fbSBrett Creeley link_speed_mbps = SPEED_UNKNOWN;
14325ec8b7d1SJesse Brandeburg break;
14335ec8b7d1SJesse Brandeburg }
14345ec8b7d1SJesse Brandeburg
1435e0ef26fbSBrett Creeley print_link_msg:
1436e0ef26fbSBrett Creeley if (link_speed_mbps > SPEED_1000) {
1437e0ef26fbSBrett Creeley if (link_speed_mbps == SPEED_2500)
1438e0ef26fbSBrett Creeley snprintf(speed, IAVF_MAX_SPEED_STRLEN, "2.5 Gbps");
1439e0ef26fbSBrett Creeley else
1440e0ef26fbSBrett Creeley /* convert to Gbps inline */
1441e0ef26fbSBrett Creeley snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s",
1442e0ef26fbSBrett Creeley link_speed_mbps / 1000, "Gbps");
1443e0ef26fbSBrett Creeley } else if (link_speed_mbps == SPEED_UNKNOWN) {
1444e0ef26fbSBrett Creeley snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%s", "Unknown Mbps");
1445e0ef26fbSBrett Creeley } else {
1446c2fbcc94SKaren Sornek snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s",
1447e0ef26fbSBrett Creeley link_speed_mbps, "Mbps");
1448e0ef26fbSBrett Creeley }
1449e0ef26fbSBrett Creeley
1450e0ef26fbSBrett Creeley netdev_info(netdev, "NIC Link is Up Speed is %s Full Duplex\n", speed);
1451e0ef26fbSBrett Creeley kfree(speed);
1452e0ef26fbSBrett Creeley }
1453e0ef26fbSBrett Creeley
1454e0ef26fbSBrett Creeley /**
1455e0ef26fbSBrett Creeley * iavf_get_vpe_link_status
1456e0ef26fbSBrett Creeley * @adapter: adapter structure
1457e0ef26fbSBrett Creeley * @vpe: virtchnl_pf_event structure
1458e0ef26fbSBrett Creeley *
1459e0ef26fbSBrett Creeley * Helper function for determining the link status
1460e0ef26fbSBrett Creeley **/
1461e0ef26fbSBrett Creeley static bool
iavf_get_vpe_link_status(struct iavf_adapter * adapter,struct virtchnl_pf_event * vpe)1462e0ef26fbSBrett Creeley iavf_get_vpe_link_status(struct iavf_adapter *adapter,
1463e0ef26fbSBrett Creeley struct virtchnl_pf_event *vpe)
1464e0ef26fbSBrett Creeley {
1465e0ef26fbSBrett Creeley if (ADV_LINK_SUPPORT(adapter))
1466e0ef26fbSBrett Creeley return vpe->event_data.link_event_adv.link_status;
1467e0ef26fbSBrett Creeley else
1468e0ef26fbSBrett Creeley return vpe->event_data.link_event.link_status;
1469e0ef26fbSBrett Creeley }
1470e0ef26fbSBrett Creeley
1471e0ef26fbSBrett Creeley /**
1472e0ef26fbSBrett Creeley * iavf_set_adapter_link_speed_from_vpe
1473e0ef26fbSBrett Creeley * @adapter: adapter structure for which we are setting the link speed
1474e0ef26fbSBrett Creeley * @vpe: virtchnl_pf_event structure that contains the link speed we are setting
1475e0ef26fbSBrett Creeley *
1476e0ef26fbSBrett Creeley * Helper function for setting iavf_adapter link speed
1477e0ef26fbSBrett Creeley **/
1478e0ef26fbSBrett Creeley static void
iavf_set_adapter_link_speed_from_vpe(struct iavf_adapter * adapter,struct virtchnl_pf_event * vpe)1479e0ef26fbSBrett Creeley iavf_set_adapter_link_speed_from_vpe(struct iavf_adapter *adapter,
1480e0ef26fbSBrett Creeley struct virtchnl_pf_event *vpe)
1481e0ef26fbSBrett Creeley {
1482e0ef26fbSBrett Creeley if (ADV_LINK_SUPPORT(adapter))
1483e0ef26fbSBrett Creeley adapter->link_speed_mbps =
1484e0ef26fbSBrett Creeley vpe->event_data.link_event_adv.link_speed;
1485e0ef26fbSBrett Creeley else
1486e0ef26fbSBrett Creeley adapter->link_speed = vpe->event_data.link_event.link_speed;
14875ec8b7d1SJesse Brandeburg }
14885ec8b7d1SJesse Brandeburg
14895ec8b7d1SJesse Brandeburg /**
1490262de08fSJesse Brandeburg * iavf_enable_channels
14915ec8b7d1SJesse Brandeburg * @adapter: adapter structure
14925ec8b7d1SJesse Brandeburg *
14935ec8b7d1SJesse Brandeburg * Request that the PF enable channels as specified by
14945ec8b7d1SJesse Brandeburg * the user via tc tool.
14955ec8b7d1SJesse Brandeburg **/
iavf_enable_channels(struct iavf_adapter * adapter)14965ec8b7d1SJesse Brandeburg void iavf_enable_channels(struct iavf_adapter *adapter)
14975ec8b7d1SJesse Brandeburg {
14985ec8b7d1SJesse Brandeburg struct virtchnl_tc_info *vti = NULL;
1499af07adbbSGustavo A. R. Silva size_t len;
15005ec8b7d1SJesse Brandeburg int i;
15015ec8b7d1SJesse Brandeburg
15025ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
15035ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
15045ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
15055ec8b7d1SJesse Brandeburg adapter->current_op);
15065ec8b7d1SJesse Brandeburg return;
15075ec8b7d1SJesse Brandeburg }
15085ec8b7d1SJesse Brandeburg
1509b0654e64SAlexander Lobakin len = virtchnl_struct_size(vti, list, adapter->num_tc);
15105ec8b7d1SJesse Brandeburg vti = kzalloc(len, GFP_KERNEL);
15115ec8b7d1SJesse Brandeburg if (!vti)
15125ec8b7d1SJesse Brandeburg return;
15135ec8b7d1SJesse Brandeburg vti->num_tc = adapter->num_tc;
15145ec8b7d1SJesse Brandeburg for (i = 0; i < vti->num_tc; i++) {
15155ec8b7d1SJesse Brandeburg vti->list[i].count = adapter->ch_config.ch_info[i].count;
15165ec8b7d1SJesse Brandeburg vti->list[i].offset = adapter->ch_config.ch_info[i].offset;
15175ec8b7d1SJesse Brandeburg vti->list[i].pad = 0;
15185ec8b7d1SJesse Brandeburg vti->list[i].max_tx_rate =
15195ec8b7d1SJesse Brandeburg adapter->ch_config.ch_info[i].max_tx_rate;
15205ec8b7d1SJesse Brandeburg }
15215ec8b7d1SJesse Brandeburg
15225ec8b7d1SJesse Brandeburg adapter->ch_config.state = __IAVF_TC_RUNNING;
15235ec8b7d1SJesse Brandeburg adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
15245ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ENABLE_CHANNELS;
15255ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ENABLE_CHANNELS;
15265ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_CHANNELS, (u8 *)vti, len);
15275ec8b7d1SJesse Brandeburg kfree(vti);
15285ec8b7d1SJesse Brandeburg }
15295ec8b7d1SJesse Brandeburg
15305ec8b7d1SJesse Brandeburg /**
1531262de08fSJesse Brandeburg * iavf_disable_channels
15325ec8b7d1SJesse Brandeburg * @adapter: adapter structure
15335ec8b7d1SJesse Brandeburg *
15345ec8b7d1SJesse Brandeburg * Request that the PF disable channels that are configured
15355ec8b7d1SJesse Brandeburg **/
iavf_disable_channels(struct iavf_adapter * adapter)15365ec8b7d1SJesse Brandeburg void iavf_disable_channels(struct iavf_adapter *adapter)
15375ec8b7d1SJesse Brandeburg {
15385ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
15395ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
15405ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
15415ec8b7d1SJesse Brandeburg adapter->current_op);
15425ec8b7d1SJesse Brandeburg return;
15435ec8b7d1SJesse Brandeburg }
15445ec8b7d1SJesse Brandeburg
15455ec8b7d1SJesse Brandeburg adapter->ch_config.state = __IAVF_TC_INVALID;
15465ec8b7d1SJesse Brandeburg adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
15475ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DISABLE_CHANNELS;
15485ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DISABLE_CHANNELS;
15495ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_CHANNELS, NULL, 0);
15505ec8b7d1SJesse Brandeburg }
15515ec8b7d1SJesse Brandeburg
15525ec8b7d1SJesse Brandeburg /**
15535ec8b7d1SJesse Brandeburg * iavf_print_cloud_filter
15545ec8b7d1SJesse Brandeburg * @adapter: adapter structure
15555ec8b7d1SJesse Brandeburg * @f: cloud filter to print
15565ec8b7d1SJesse Brandeburg *
15575ec8b7d1SJesse Brandeburg * Print the cloud filter
15585ec8b7d1SJesse Brandeburg **/
iavf_print_cloud_filter(struct iavf_adapter * adapter,struct virtchnl_filter * f)15595ec8b7d1SJesse Brandeburg static void iavf_print_cloud_filter(struct iavf_adapter *adapter,
15605ec8b7d1SJesse Brandeburg struct virtchnl_filter *f)
15615ec8b7d1SJesse Brandeburg {
15625ec8b7d1SJesse Brandeburg switch (f->flow_type) {
15635ec8b7d1SJesse Brandeburg case VIRTCHNL_TCP_V4_FLOW:
15645ec8b7d1SJesse Brandeburg 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",
15655ec8b7d1SJesse Brandeburg &f->data.tcp_spec.dst_mac,
15665ec8b7d1SJesse Brandeburg &f->data.tcp_spec.src_mac,
15675ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.vlan_id),
15685ec8b7d1SJesse Brandeburg &f->data.tcp_spec.dst_ip[0],
15695ec8b7d1SJesse Brandeburg &f->data.tcp_spec.src_ip[0],
15705ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.dst_port),
15715ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.src_port));
15725ec8b7d1SJesse Brandeburg break;
15735ec8b7d1SJesse Brandeburg case VIRTCHNL_TCP_V6_FLOW:
15745ec8b7d1SJesse Brandeburg 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",
15755ec8b7d1SJesse Brandeburg &f->data.tcp_spec.dst_mac,
15765ec8b7d1SJesse Brandeburg &f->data.tcp_spec.src_mac,
15775ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.vlan_id),
15785ec8b7d1SJesse Brandeburg &f->data.tcp_spec.dst_ip,
15795ec8b7d1SJesse Brandeburg &f->data.tcp_spec.src_ip,
15805ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.dst_port),
15815ec8b7d1SJesse Brandeburg ntohs(f->data.tcp_spec.src_port));
15825ec8b7d1SJesse Brandeburg break;
15835ec8b7d1SJesse Brandeburg }
15845ec8b7d1SJesse Brandeburg }
15855ec8b7d1SJesse Brandeburg
15865ec8b7d1SJesse Brandeburg /**
15875ec8b7d1SJesse Brandeburg * iavf_add_cloud_filter
15885ec8b7d1SJesse Brandeburg * @adapter: adapter structure
15895ec8b7d1SJesse Brandeburg *
15905ec8b7d1SJesse Brandeburg * Request that the PF add cloud filters as specified
15915ec8b7d1SJesse Brandeburg * by the user via tc tool.
15925ec8b7d1SJesse Brandeburg **/
iavf_add_cloud_filter(struct iavf_adapter * adapter)15935ec8b7d1SJesse Brandeburg void iavf_add_cloud_filter(struct iavf_adapter *adapter)
15945ec8b7d1SJesse Brandeburg {
15955ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf;
15965ec8b7d1SJesse Brandeburg struct virtchnl_filter *f;
15975ec8b7d1SJesse Brandeburg int len = 0, count = 0;
15985ec8b7d1SJesse Brandeburg
15995ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
16005ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
16015ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot add cloud filter, command %d pending\n",
16025ec8b7d1SJesse Brandeburg adapter->current_op);
16035ec8b7d1SJesse Brandeburg return;
16045ec8b7d1SJesse Brandeburg }
16055ec8b7d1SJesse Brandeburg list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
16065ec8b7d1SJesse Brandeburg if (cf->add) {
16075ec8b7d1SJesse Brandeburg count++;
16085ec8b7d1SJesse Brandeburg break;
16095ec8b7d1SJesse Brandeburg }
16105ec8b7d1SJesse Brandeburg }
16115ec8b7d1SJesse Brandeburg if (!count) {
16125ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
16135ec8b7d1SJesse Brandeburg return;
16145ec8b7d1SJesse Brandeburg }
16155ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_ADD_CLOUD_FILTER;
16165ec8b7d1SJesse Brandeburg
16175ec8b7d1SJesse Brandeburg len = sizeof(struct virtchnl_filter);
16185ec8b7d1SJesse Brandeburg f = kzalloc(len, GFP_KERNEL);
16195ec8b7d1SJesse Brandeburg if (!f)
16205ec8b7d1SJesse Brandeburg return;
16215ec8b7d1SJesse Brandeburg
16225ec8b7d1SJesse Brandeburg list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
16235ec8b7d1SJesse Brandeburg if (cf->add) {
16245ec8b7d1SJesse Brandeburg memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
16255ec8b7d1SJesse Brandeburg cf->add = false;
16265ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_ADD_PENDING;
16275ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_CLOUD_FILTER,
16285ec8b7d1SJesse Brandeburg (u8 *)f, len);
16295ec8b7d1SJesse Brandeburg }
16305ec8b7d1SJesse Brandeburg }
16315ec8b7d1SJesse Brandeburg kfree(f);
16325ec8b7d1SJesse Brandeburg }
16335ec8b7d1SJesse Brandeburg
16345ec8b7d1SJesse Brandeburg /**
16355ec8b7d1SJesse Brandeburg * iavf_del_cloud_filter
16365ec8b7d1SJesse Brandeburg * @adapter: adapter structure
16375ec8b7d1SJesse Brandeburg *
16385ec8b7d1SJesse Brandeburg * Request that the PF delete cloud filters as specified
16395ec8b7d1SJesse Brandeburg * by the user via tc tool.
16405ec8b7d1SJesse Brandeburg **/
iavf_del_cloud_filter(struct iavf_adapter * adapter)16415ec8b7d1SJesse Brandeburg void iavf_del_cloud_filter(struct iavf_adapter *adapter)
16425ec8b7d1SJesse Brandeburg {
16435ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf, *cftmp;
16445ec8b7d1SJesse Brandeburg struct virtchnl_filter *f;
16455ec8b7d1SJesse Brandeburg int len = 0, count = 0;
16465ec8b7d1SJesse Brandeburg
16475ec8b7d1SJesse Brandeburg if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
16485ec8b7d1SJesse Brandeburg /* bail because we already have a command pending */
16495ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Cannot remove cloud filter, command %d pending\n",
16505ec8b7d1SJesse Brandeburg adapter->current_op);
16515ec8b7d1SJesse Brandeburg return;
16525ec8b7d1SJesse Brandeburg }
16535ec8b7d1SJesse Brandeburg list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
16545ec8b7d1SJesse Brandeburg if (cf->del) {
16555ec8b7d1SJesse Brandeburg count++;
16565ec8b7d1SJesse Brandeburg break;
16575ec8b7d1SJesse Brandeburg }
16585ec8b7d1SJesse Brandeburg }
16595ec8b7d1SJesse Brandeburg if (!count) {
16605ec8b7d1SJesse Brandeburg adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
16615ec8b7d1SJesse Brandeburg return;
16625ec8b7d1SJesse Brandeburg }
16635ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_DEL_CLOUD_FILTER;
16645ec8b7d1SJesse Brandeburg
16655ec8b7d1SJesse Brandeburg len = sizeof(struct virtchnl_filter);
16665ec8b7d1SJesse Brandeburg f = kzalloc(len, GFP_KERNEL);
16675ec8b7d1SJesse Brandeburg if (!f)
16685ec8b7d1SJesse Brandeburg return;
16695ec8b7d1SJesse Brandeburg
16705ec8b7d1SJesse Brandeburg list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, list) {
16715ec8b7d1SJesse Brandeburg if (cf->del) {
16725ec8b7d1SJesse Brandeburg memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
16735ec8b7d1SJesse Brandeburg cf->del = false;
16745ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_DEL_PENDING;
16755ec8b7d1SJesse Brandeburg iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_CLOUD_FILTER,
16765ec8b7d1SJesse Brandeburg (u8 *)f, len);
16775ec8b7d1SJesse Brandeburg }
16785ec8b7d1SJesse Brandeburg }
16795ec8b7d1SJesse Brandeburg kfree(f);
16805ec8b7d1SJesse Brandeburg }
16815ec8b7d1SJesse Brandeburg
16825ec8b7d1SJesse Brandeburg /**
16830dbfbabbSHaiyue Wang * iavf_add_fdir_filter
16840dbfbabbSHaiyue Wang * @adapter: the VF adapter structure
16850dbfbabbSHaiyue Wang *
16860dbfbabbSHaiyue Wang * Request that the PF add Flow Director filters as specified
16870dbfbabbSHaiyue Wang * by the user via ethtool.
16880dbfbabbSHaiyue Wang **/
iavf_add_fdir_filter(struct iavf_adapter * adapter)16890dbfbabbSHaiyue Wang void iavf_add_fdir_filter(struct iavf_adapter *adapter)
16900dbfbabbSHaiyue Wang {
16910dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir;
16920dbfbabbSHaiyue Wang struct virtchnl_fdir_add *f;
16930dbfbabbSHaiyue Wang bool process_fltr = false;
16940dbfbabbSHaiyue Wang int len;
16950dbfbabbSHaiyue Wang
16960dbfbabbSHaiyue Wang if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
16970dbfbabbSHaiyue Wang /* bail because we already have a command pending */
16980dbfbabbSHaiyue Wang dev_err(&adapter->pdev->dev, "Cannot add Flow Director filter, command %d pending\n",
16990dbfbabbSHaiyue Wang adapter->current_op);
17000dbfbabbSHaiyue Wang return;
17010dbfbabbSHaiyue Wang }
17020dbfbabbSHaiyue Wang
17030dbfbabbSHaiyue Wang len = sizeof(struct virtchnl_fdir_add);
17040dbfbabbSHaiyue Wang f = kzalloc(len, GFP_KERNEL);
17050dbfbabbSHaiyue Wang if (!f)
17060dbfbabbSHaiyue Wang return;
17070dbfbabbSHaiyue Wang
17080dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
17090dbfbabbSHaiyue Wang list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
17100dbfbabbSHaiyue Wang if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
17110dbfbabbSHaiyue Wang process_fltr = true;
17120dbfbabbSHaiyue Wang fdir->state = IAVF_FDIR_FLTR_ADD_PENDING;
17130dbfbabbSHaiyue Wang memcpy(f, &fdir->vc_add_msg, len);
17140dbfbabbSHaiyue Wang break;
17150dbfbabbSHaiyue Wang }
17160dbfbabbSHaiyue Wang }
17170dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
17180dbfbabbSHaiyue Wang
17190dbfbabbSHaiyue Wang if (!process_fltr) {
17200dbfbabbSHaiyue Wang /* prevent iavf_add_fdir_filter() from being called when there
17210dbfbabbSHaiyue Wang * are no filters to add
17220dbfbabbSHaiyue Wang */
17230dbfbabbSHaiyue Wang adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_FDIR_FILTER;
17240dbfbabbSHaiyue Wang kfree(f);
17250dbfbabbSHaiyue Wang return;
17260dbfbabbSHaiyue Wang }
17270dbfbabbSHaiyue Wang adapter->current_op = VIRTCHNL_OP_ADD_FDIR_FILTER;
17280dbfbabbSHaiyue Wang iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_FDIR_FILTER, (u8 *)f, len);
17290dbfbabbSHaiyue Wang kfree(f);
17300dbfbabbSHaiyue Wang }
17310dbfbabbSHaiyue Wang
17320dbfbabbSHaiyue Wang /**
17330dbfbabbSHaiyue Wang * iavf_del_fdir_filter
17340dbfbabbSHaiyue Wang * @adapter: the VF adapter structure
17350dbfbabbSHaiyue Wang *
17360dbfbabbSHaiyue Wang * Request that the PF delete Flow Director filters as specified
17370dbfbabbSHaiyue Wang * by the user via ethtool.
17380dbfbabbSHaiyue Wang **/
iavf_del_fdir_filter(struct iavf_adapter * adapter)17390dbfbabbSHaiyue Wang void iavf_del_fdir_filter(struct iavf_adapter *adapter)
17400dbfbabbSHaiyue Wang {
1741*3beb9d66SPiotr Gardocki struct virtchnl_fdir_del f = {};
17420dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir;
17430dbfbabbSHaiyue Wang bool process_fltr = false;
17440dbfbabbSHaiyue Wang int len;
17450dbfbabbSHaiyue Wang
17460dbfbabbSHaiyue Wang if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
17470dbfbabbSHaiyue Wang /* bail because we already have a command pending */
17480dbfbabbSHaiyue Wang dev_err(&adapter->pdev->dev, "Cannot remove Flow Director filter, command %d pending\n",
17490dbfbabbSHaiyue Wang adapter->current_op);
17500dbfbabbSHaiyue Wang return;
17510dbfbabbSHaiyue Wang }
17520dbfbabbSHaiyue Wang
17530dbfbabbSHaiyue Wang len = sizeof(struct virtchnl_fdir_del);
17540dbfbabbSHaiyue Wang
17550dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
17560dbfbabbSHaiyue Wang list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
17570dbfbabbSHaiyue Wang if (fdir->state == IAVF_FDIR_FLTR_DEL_REQUEST) {
17580dbfbabbSHaiyue Wang process_fltr = true;
17590dbfbabbSHaiyue Wang f.vsi_id = fdir->vc_add_msg.vsi_id;
17600dbfbabbSHaiyue Wang f.flow_id = fdir->flow_id;
17610dbfbabbSHaiyue Wang fdir->state = IAVF_FDIR_FLTR_DEL_PENDING;
17620dbfbabbSHaiyue Wang break;
1763*3beb9d66SPiotr Gardocki } else if (fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST) {
1764*3beb9d66SPiotr Gardocki process_fltr = true;
1765*3beb9d66SPiotr Gardocki f.vsi_id = fdir->vc_add_msg.vsi_id;
1766*3beb9d66SPiotr Gardocki f.flow_id = fdir->flow_id;
1767*3beb9d66SPiotr Gardocki fdir->state = IAVF_FDIR_FLTR_DIS_PENDING;
1768*3beb9d66SPiotr Gardocki break;
17690dbfbabbSHaiyue Wang }
17700dbfbabbSHaiyue Wang }
17710dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
17720dbfbabbSHaiyue Wang
17730dbfbabbSHaiyue Wang if (!process_fltr) {
17740dbfbabbSHaiyue Wang adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_FDIR_FILTER;
17750dbfbabbSHaiyue Wang return;
17760dbfbabbSHaiyue Wang }
17770dbfbabbSHaiyue Wang
17780dbfbabbSHaiyue Wang adapter->current_op = VIRTCHNL_OP_DEL_FDIR_FILTER;
17790dbfbabbSHaiyue Wang iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_FDIR_FILTER, (u8 *)&f, len);
17800dbfbabbSHaiyue Wang }
17810dbfbabbSHaiyue Wang
17820dbfbabbSHaiyue Wang /**
17830aaeb4fbSHaiyue Wang * iavf_add_adv_rss_cfg
17840aaeb4fbSHaiyue Wang * @adapter: the VF adapter structure
17850aaeb4fbSHaiyue Wang *
17860aaeb4fbSHaiyue Wang * Request that the PF add RSS configuration as specified
17870aaeb4fbSHaiyue Wang * by the user via ethtool.
17880aaeb4fbSHaiyue Wang **/
iavf_add_adv_rss_cfg(struct iavf_adapter * adapter)17890aaeb4fbSHaiyue Wang void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter)
17900aaeb4fbSHaiyue Wang {
17910aaeb4fbSHaiyue Wang struct virtchnl_rss_cfg *rss_cfg;
17920aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss;
17930aaeb4fbSHaiyue Wang bool process_rss = false;
17940aaeb4fbSHaiyue Wang int len;
17950aaeb4fbSHaiyue Wang
17960aaeb4fbSHaiyue Wang if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
17970aaeb4fbSHaiyue Wang /* bail because we already have a command pending */
17980aaeb4fbSHaiyue Wang dev_err(&adapter->pdev->dev, "Cannot add RSS configuration, command %d pending\n",
17990aaeb4fbSHaiyue Wang adapter->current_op);
18000aaeb4fbSHaiyue Wang return;
18010aaeb4fbSHaiyue Wang }
18020aaeb4fbSHaiyue Wang
18030aaeb4fbSHaiyue Wang len = sizeof(struct virtchnl_rss_cfg);
18040aaeb4fbSHaiyue Wang rss_cfg = kzalloc(len, GFP_KERNEL);
18050aaeb4fbSHaiyue Wang if (!rss_cfg)
18060aaeb4fbSHaiyue Wang return;
18070aaeb4fbSHaiyue Wang
18080aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
18090aaeb4fbSHaiyue Wang list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
18100aaeb4fbSHaiyue Wang if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
18110aaeb4fbSHaiyue Wang process_rss = true;
18120aaeb4fbSHaiyue Wang rss->state = IAVF_ADV_RSS_ADD_PENDING;
18130aaeb4fbSHaiyue Wang memcpy(rss_cfg, &rss->cfg_msg, len);
18145ab91e05SHaiyue Wang iavf_print_adv_rss_cfg(adapter, rss,
18155ab91e05SHaiyue Wang "Input set change for",
18165ab91e05SHaiyue Wang "is pending");
18170aaeb4fbSHaiyue Wang break;
18180aaeb4fbSHaiyue Wang }
18190aaeb4fbSHaiyue Wang }
18200aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
18210aaeb4fbSHaiyue Wang
18220aaeb4fbSHaiyue Wang if (process_rss) {
18230aaeb4fbSHaiyue Wang adapter->current_op = VIRTCHNL_OP_ADD_RSS_CFG;
18240aaeb4fbSHaiyue Wang iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_RSS_CFG,
18250aaeb4fbSHaiyue Wang (u8 *)rss_cfg, len);
18260aaeb4fbSHaiyue Wang } else {
18270aaeb4fbSHaiyue Wang adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_ADV_RSS_CFG;
18280aaeb4fbSHaiyue Wang }
18290aaeb4fbSHaiyue Wang
18300aaeb4fbSHaiyue Wang kfree(rss_cfg);
18310aaeb4fbSHaiyue Wang }
18320aaeb4fbSHaiyue Wang
18330aaeb4fbSHaiyue Wang /**
18340aaeb4fbSHaiyue Wang * iavf_del_adv_rss_cfg
18350aaeb4fbSHaiyue Wang * @adapter: the VF adapter structure
18360aaeb4fbSHaiyue Wang *
18370aaeb4fbSHaiyue Wang * Request that the PF delete RSS configuration as specified
18380aaeb4fbSHaiyue Wang * by the user via ethtool.
18390aaeb4fbSHaiyue Wang **/
iavf_del_adv_rss_cfg(struct iavf_adapter * adapter)18400aaeb4fbSHaiyue Wang void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter)
18410aaeb4fbSHaiyue Wang {
18420aaeb4fbSHaiyue Wang struct virtchnl_rss_cfg *rss_cfg;
18430aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss;
18440aaeb4fbSHaiyue Wang bool process_rss = false;
18450aaeb4fbSHaiyue Wang int len;
18460aaeb4fbSHaiyue Wang
18470aaeb4fbSHaiyue Wang if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
18480aaeb4fbSHaiyue Wang /* bail because we already have a command pending */
18490aaeb4fbSHaiyue Wang dev_err(&adapter->pdev->dev, "Cannot remove RSS configuration, command %d pending\n",
18500aaeb4fbSHaiyue Wang adapter->current_op);
18510aaeb4fbSHaiyue Wang return;
18520aaeb4fbSHaiyue Wang }
18530aaeb4fbSHaiyue Wang
18540aaeb4fbSHaiyue Wang len = sizeof(struct virtchnl_rss_cfg);
18550aaeb4fbSHaiyue Wang rss_cfg = kzalloc(len, GFP_KERNEL);
18560aaeb4fbSHaiyue Wang if (!rss_cfg)
18570aaeb4fbSHaiyue Wang return;
18580aaeb4fbSHaiyue Wang
18590aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
18600aaeb4fbSHaiyue Wang list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
18610aaeb4fbSHaiyue Wang if (rss->state == IAVF_ADV_RSS_DEL_REQUEST) {
18620aaeb4fbSHaiyue Wang process_rss = true;
18630aaeb4fbSHaiyue Wang rss->state = IAVF_ADV_RSS_DEL_PENDING;
18640aaeb4fbSHaiyue Wang memcpy(rss_cfg, &rss->cfg_msg, len);
18650aaeb4fbSHaiyue Wang break;
18660aaeb4fbSHaiyue Wang }
18670aaeb4fbSHaiyue Wang }
18680aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
18690aaeb4fbSHaiyue Wang
18700aaeb4fbSHaiyue Wang if (process_rss) {
18710aaeb4fbSHaiyue Wang adapter->current_op = VIRTCHNL_OP_DEL_RSS_CFG;
18720aaeb4fbSHaiyue Wang iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_RSS_CFG,
18730aaeb4fbSHaiyue Wang (u8 *)rss_cfg, len);
18740aaeb4fbSHaiyue Wang } else {
18750aaeb4fbSHaiyue Wang adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
18760aaeb4fbSHaiyue Wang }
18770aaeb4fbSHaiyue Wang
18780aaeb4fbSHaiyue Wang kfree(rss_cfg);
18790aaeb4fbSHaiyue Wang }
18800aaeb4fbSHaiyue Wang
18810aaeb4fbSHaiyue Wang /**
18825ec8b7d1SJesse Brandeburg * iavf_request_reset
18835ec8b7d1SJesse Brandeburg * @adapter: adapter structure
18845ec8b7d1SJesse Brandeburg *
18855ec8b7d1SJesse Brandeburg * Request that the PF reset this VF. No response is expected.
18865ec8b7d1SJesse Brandeburg **/
iavf_request_reset(struct iavf_adapter * adapter)1887bae569d0SMateusz Palczewski int iavf_request_reset(struct iavf_adapter *adapter)
18885ec8b7d1SJesse Brandeburg {
1889bae569d0SMateusz Palczewski int err;
18905ec8b7d1SJesse Brandeburg /* Don't check CURRENT_OP - this is always higher priority */
1891bae569d0SMateusz Palczewski err = iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
18925ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_UNKNOWN;
1893bae569d0SMateusz Palczewski return err;
18945ec8b7d1SJesse Brandeburg }
18955ec8b7d1SJesse Brandeburg
18965ec8b7d1SJesse Brandeburg /**
18972cf29e55SMichal Maloszewski * iavf_netdev_features_vlan_strip_set - update vlan strip status
18982cf29e55SMichal Maloszewski * @netdev: ptr to netdev being adjusted
18992cf29e55SMichal Maloszewski * @enable: enable or disable vlan strip
19002cf29e55SMichal Maloszewski *
19012cf29e55SMichal Maloszewski * Helper function to change vlan strip status in netdev->features.
19022cf29e55SMichal Maloszewski */
iavf_netdev_features_vlan_strip_set(struct net_device * netdev,const bool enable)19032cf29e55SMichal Maloszewski static void iavf_netdev_features_vlan_strip_set(struct net_device *netdev,
19042cf29e55SMichal Maloszewski const bool enable)
19052cf29e55SMichal Maloszewski {
19062cf29e55SMichal Maloszewski if (enable)
19072cf29e55SMichal Maloszewski netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
19082cf29e55SMichal Maloszewski else
19092cf29e55SMichal Maloszewski netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
19102cf29e55SMichal Maloszewski }
19112cf29e55SMichal Maloszewski
19122cf29e55SMichal Maloszewski /**
1913*3beb9d66SPiotr Gardocki * iavf_activate_fdir_filters - Reactivate all FDIR filters after a reset
1914*3beb9d66SPiotr Gardocki * @adapter: private adapter structure
1915*3beb9d66SPiotr Gardocki *
1916*3beb9d66SPiotr Gardocki * Called after a reset to re-add all FDIR filters and delete some of them
1917*3beb9d66SPiotr Gardocki * if they were pending to be deleted.
1918*3beb9d66SPiotr Gardocki */
iavf_activate_fdir_filters(struct iavf_adapter * adapter)1919*3beb9d66SPiotr Gardocki static void iavf_activate_fdir_filters(struct iavf_adapter *adapter)
1920*3beb9d66SPiotr Gardocki {
1921*3beb9d66SPiotr Gardocki struct iavf_fdir_fltr *f, *ftmp;
1922*3beb9d66SPiotr Gardocki bool add_filters = false;
1923*3beb9d66SPiotr Gardocki
1924*3beb9d66SPiotr Gardocki spin_lock_bh(&adapter->fdir_fltr_lock);
1925*3beb9d66SPiotr Gardocki list_for_each_entry_safe(f, ftmp, &adapter->fdir_list_head, list) {
1926*3beb9d66SPiotr Gardocki if (f->state == IAVF_FDIR_FLTR_ADD_REQUEST ||
1927*3beb9d66SPiotr Gardocki f->state == IAVF_FDIR_FLTR_ADD_PENDING ||
1928*3beb9d66SPiotr Gardocki f->state == IAVF_FDIR_FLTR_ACTIVE) {
1929*3beb9d66SPiotr Gardocki /* All filters and requests have been removed in PF,
1930*3beb9d66SPiotr Gardocki * restore them
1931*3beb9d66SPiotr Gardocki */
1932*3beb9d66SPiotr Gardocki f->state = IAVF_FDIR_FLTR_ADD_REQUEST;
1933*3beb9d66SPiotr Gardocki add_filters = true;
1934*3beb9d66SPiotr Gardocki } else if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST ||
1935*3beb9d66SPiotr Gardocki f->state == IAVF_FDIR_FLTR_DIS_PENDING) {
1936*3beb9d66SPiotr Gardocki /* Link down state, leave filters as inactive */
1937*3beb9d66SPiotr Gardocki f->state = IAVF_FDIR_FLTR_INACTIVE;
1938*3beb9d66SPiotr Gardocki } else if (f->state == IAVF_FDIR_FLTR_DEL_REQUEST ||
1939*3beb9d66SPiotr Gardocki f->state == IAVF_FDIR_FLTR_DEL_PENDING) {
1940*3beb9d66SPiotr Gardocki /* Delete filters that were pending to be deleted, the
1941*3beb9d66SPiotr Gardocki * list on PF is already cleared after a reset
1942*3beb9d66SPiotr Gardocki */
1943*3beb9d66SPiotr Gardocki list_del(&f->list);
1944*3beb9d66SPiotr Gardocki kfree(f);
1945*3beb9d66SPiotr Gardocki adapter->fdir_active_fltr--;
1946*3beb9d66SPiotr Gardocki }
1947*3beb9d66SPiotr Gardocki }
1948*3beb9d66SPiotr Gardocki spin_unlock_bh(&adapter->fdir_fltr_lock);
1949*3beb9d66SPiotr Gardocki
1950*3beb9d66SPiotr Gardocki if (add_filters)
1951*3beb9d66SPiotr Gardocki adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER;
1952*3beb9d66SPiotr Gardocki }
1953*3beb9d66SPiotr Gardocki
1954*3beb9d66SPiotr Gardocki /**
19555ec8b7d1SJesse Brandeburg * iavf_virtchnl_completion
19565ec8b7d1SJesse Brandeburg * @adapter: adapter structure
19575ec8b7d1SJesse Brandeburg * @v_opcode: opcode sent by PF
19585ec8b7d1SJesse Brandeburg * @v_retval: retval sent by PF
19595ec8b7d1SJesse Brandeburg * @msg: message sent by PF
19605ec8b7d1SJesse Brandeburg * @msglen: message length
19615ec8b7d1SJesse Brandeburg *
19625ec8b7d1SJesse Brandeburg * Asynchronous completion function for admin queue messages. Rather than busy
19635ec8b7d1SJesse Brandeburg * wait, we fire off our requests and assume that no errors will be returned.
19645ec8b7d1SJesse Brandeburg * This function handles the reply messages.
19655ec8b7d1SJesse Brandeburg **/
iavf_virtchnl_completion(struct iavf_adapter * adapter,enum virtchnl_ops v_opcode,enum iavf_status v_retval,u8 * msg,u16 msglen)19665ec8b7d1SJesse Brandeburg void iavf_virtchnl_completion(struct iavf_adapter *adapter,
196780754bbcSSergey Nemov enum virtchnl_ops v_opcode,
196880754bbcSSergey Nemov enum iavf_status v_retval, u8 *msg, u16 msglen)
19695ec8b7d1SJesse Brandeburg {
19705ec8b7d1SJesse Brandeburg struct net_device *netdev = adapter->netdev;
19715ec8b7d1SJesse Brandeburg
19725ec8b7d1SJesse Brandeburg if (v_opcode == VIRTCHNL_OP_EVENT) {
19735ec8b7d1SJesse Brandeburg struct virtchnl_pf_event *vpe =
19745ec8b7d1SJesse Brandeburg (struct virtchnl_pf_event *)msg;
1975e0ef26fbSBrett Creeley bool link_up = iavf_get_vpe_link_status(adapter, vpe);
19765ec8b7d1SJesse Brandeburg
19775ec8b7d1SJesse Brandeburg switch (vpe->event) {
19785ec8b7d1SJesse Brandeburg case VIRTCHNL_EVENT_LINK_CHANGE:
1979e0ef26fbSBrett Creeley iavf_set_adapter_link_speed_from_vpe(adapter, vpe);
19805ec8b7d1SJesse Brandeburg
19815ec8b7d1SJesse Brandeburg /* we've already got the right link status, bail */
19825ec8b7d1SJesse Brandeburg if (adapter->link_up == link_up)
19835ec8b7d1SJesse Brandeburg break;
19845ec8b7d1SJesse Brandeburg
19855ec8b7d1SJesse Brandeburg if (link_up) {
19865ec8b7d1SJesse Brandeburg /* If we get link up message and start queues
19875ec8b7d1SJesse Brandeburg * before our queues are configured it will
19885ec8b7d1SJesse Brandeburg * trigger a TX hang. In that case, just ignore
19895ec8b7d1SJesse Brandeburg * the link status message,we'll get another one
19905ec8b7d1SJesse Brandeburg * after we enable queues and actually prepared
19915ec8b7d1SJesse Brandeburg * to send traffic.
19925ec8b7d1SJesse Brandeburg */
19935ec8b7d1SJesse Brandeburg if (adapter->state != __IAVF_RUNNING)
19945ec8b7d1SJesse Brandeburg break;
19955ec8b7d1SJesse Brandeburg
19965ec8b7d1SJesse Brandeburg /* For ADq enabled VF, we reconfigure VSIs and
19975ec8b7d1SJesse Brandeburg * re-allocate queues. Hence wait till all
19985ec8b7d1SJesse Brandeburg * queues are enabled.
19995ec8b7d1SJesse Brandeburg */
20005ec8b7d1SJesse Brandeburg if (adapter->flags &
20015ec8b7d1SJesse Brandeburg IAVF_FLAG_QUEUES_DISABLED)
20025ec8b7d1SJesse Brandeburg break;
20035ec8b7d1SJesse Brandeburg }
20045ec8b7d1SJesse Brandeburg
20055ec8b7d1SJesse Brandeburg adapter->link_up = link_up;
20065ec8b7d1SJesse Brandeburg if (link_up) {
20075ec8b7d1SJesse Brandeburg netif_tx_start_all_queues(netdev);
20085ec8b7d1SJesse Brandeburg netif_carrier_on(netdev);
20095ec8b7d1SJesse Brandeburg } else {
20105ec8b7d1SJesse Brandeburg netif_tx_stop_all_queues(netdev);
20115ec8b7d1SJesse Brandeburg netif_carrier_off(netdev);
20125ec8b7d1SJesse Brandeburg }
20135ec8b7d1SJesse Brandeburg iavf_print_link_message(adapter);
20145ec8b7d1SJesse Brandeburg break;
20155ec8b7d1SJesse Brandeburg case VIRTCHNL_EVENT_RESET_IMPENDING:
2016fbe66f57SKaren Sornek dev_info(&adapter->pdev->dev, "Reset indication received from the PF\n");
20175ec8b7d1SJesse Brandeburg if (!(adapter->flags & IAVF_FLAG_RESET_PENDING)) {
20185ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Scheduling reset task\n");
2019c34743daSAhmed Zaki iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING);
20205ec8b7d1SJesse Brandeburg }
20215ec8b7d1SJesse Brandeburg break;
20225ec8b7d1SJesse Brandeburg default:
20235ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Unknown event %d from PF\n",
20245ec8b7d1SJesse Brandeburg vpe->event);
20255ec8b7d1SJesse Brandeburg break;
20265ec8b7d1SJesse Brandeburg }
20275ec8b7d1SJesse Brandeburg return;
20285ec8b7d1SJesse Brandeburg }
20295ec8b7d1SJesse Brandeburg if (v_retval) {
20305ec8b7d1SJesse Brandeburg switch (v_opcode) {
20315ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ADD_VLAN:
20325ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
20335ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20345ec8b7d1SJesse Brandeburg break;
20355ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ADD_ETH_ADDR:
20365ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n",
20375ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20388da80c9dSSylwester Dziedziuch iavf_mac_add_reject(adapter);
2039c5c922b3SStefan Assmann /* restore administratively set MAC address */
2040c5c922b3SStefan Assmann ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
204135a2443dSMateusz Palczewski wake_up(&adapter->vc_waitqueue);
20425ec8b7d1SJesse Brandeburg break;
20435ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DEL_VLAN:
20445ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n",
20455ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20465ec8b7d1SJesse Brandeburg break;
20475ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DEL_ETH_ADDR:
20485ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
20495ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20505ec8b7d1SJesse Brandeburg break;
20515ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ENABLE_CHANNELS:
20525ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to configure queue channels, error %s\n",
20535ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20545ec8b7d1SJesse Brandeburg adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
20555ec8b7d1SJesse Brandeburg adapter->ch_config.state = __IAVF_TC_INVALID;
20565ec8b7d1SJesse Brandeburg netdev_reset_tc(netdev);
20575ec8b7d1SJesse Brandeburg netif_tx_start_all_queues(netdev);
20585ec8b7d1SJesse Brandeburg break;
20595ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DISABLE_CHANNELS:
20605ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "Failed to disable queue channels, error %s\n",
20615ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw, v_retval));
20625ec8b7d1SJesse Brandeburg adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
20635ec8b7d1SJesse Brandeburg adapter->ch_config.state = __IAVF_TC_RUNNING;
20645ec8b7d1SJesse Brandeburg netif_tx_start_all_queues(netdev);
20655ec8b7d1SJesse Brandeburg break;
20665ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
20675ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf, *cftmp;
20685ec8b7d1SJesse Brandeburg
20695ec8b7d1SJesse Brandeburg list_for_each_entry_safe(cf, cftmp,
20705ec8b7d1SJesse Brandeburg &adapter->cloud_filter_list,
20715ec8b7d1SJesse Brandeburg list) {
20725ec8b7d1SJesse Brandeburg if (cf->state == __IAVF_CF_ADD_PENDING) {
20735ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_INVALID;
20745ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Failed to add cloud filter, error %s\n",
20755ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw,
20765ec8b7d1SJesse Brandeburg v_retval));
20775ec8b7d1SJesse Brandeburg iavf_print_cloud_filter(adapter,
20785ec8b7d1SJesse Brandeburg &cf->f);
20795ec8b7d1SJesse Brandeburg list_del(&cf->list);
20805ec8b7d1SJesse Brandeburg kfree(cf);
20815ec8b7d1SJesse Brandeburg adapter->num_cloud_filters--;
20825ec8b7d1SJesse Brandeburg }
20835ec8b7d1SJesse Brandeburg }
20845ec8b7d1SJesse Brandeburg }
20855ec8b7d1SJesse Brandeburg break;
20865ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
20875ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf;
20885ec8b7d1SJesse Brandeburg
20895ec8b7d1SJesse Brandeburg list_for_each_entry(cf, &adapter->cloud_filter_list,
20905ec8b7d1SJesse Brandeburg list) {
20915ec8b7d1SJesse Brandeburg if (cf->state == __IAVF_CF_DEL_PENDING) {
20925ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_ACTIVE;
20935ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev, "Failed to del cloud filter, error %s\n",
20945ec8b7d1SJesse Brandeburg iavf_stat_str(&adapter->hw,
20955ec8b7d1SJesse Brandeburg v_retval));
20965ec8b7d1SJesse Brandeburg iavf_print_cloud_filter(adapter,
20975ec8b7d1SJesse Brandeburg &cf->f);
20985ec8b7d1SJesse Brandeburg }
20995ec8b7d1SJesse Brandeburg }
21005ec8b7d1SJesse Brandeburg }
21015ec8b7d1SJesse Brandeburg break;
21020dbfbabbSHaiyue Wang case VIRTCHNL_OP_ADD_FDIR_FILTER: {
21030dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir, *fdir_tmp;
21040dbfbabbSHaiyue Wang
21050dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
21060dbfbabbSHaiyue Wang list_for_each_entry_safe(fdir, fdir_tmp,
21070dbfbabbSHaiyue Wang &adapter->fdir_list_head,
21080dbfbabbSHaiyue Wang list) {
21090dbfbabbSHaiyue Wang if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING) {
21100dbfbabbSHaiyue Wang dev_info(&adapter->pdev->dev, "Failed to add Flow Director filter, error %s\n",
21110dbfbabbSHaiyue Wang iavf_stat_str(&adapter->hw,
21120dbfbabbSHaiyue Wang v_retval));
2113527691bfSHaiyue Wang iavf_print_fdir_fltr(adapter, fdir);
21140dbfbabbSHaiyue Wang if (msglen)
21150dbfbabbSHaiyue Wang dev_err(&adapter->pdev->dev,
21160dbfbabbSHaiyue Wang "%s\n", msg);
21170dbfbabbSHaiyue Wang list_del(&fdir->list);
21180dbfbabbSHaiyue Wang kfree(fdir);
21190dbfbabbSHaiyue Wang adapter->fdir_active_fltr--;
21200dbfbabbSHaiyue Wang }
21210dbfbabbSHaiyue Wang }
21220dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
21230dbfbabbSHaiyue Wang }
21240dbfbabbSHaiyue Wang break;
21250dbfbabbSHaiyue Wang case VIRTCHNL_OP_DEL_FDIR_FILTER: {
21260dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir;
21270dbfbabbSHaiyue Wang
21280dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
21290dbfbabbSHaiyue Wang list_for_each_entry(fdir, &adapter->fdir_list_head,
21300dbfbabbSHaiyue Wang list) {
2131*3beb9d66SPiotr Gardocki if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING ||
2132*3beb9d66SPiotr Gardocki fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) {
21330dbfbabbSHaiyue Wang fdir->state = IAVF_FDIR_FLTR_ACTIVE;
21340dbfbabbSHaiyue Wang dev_info(&adapter->pdev->dev, "Failed to del Flow Director filter, error %s\n",
21350dbfbabbSHaiyue Wang iavf_stat_str(&adapter->hw,
21360dbfbabbSHaiyue Wang v_retval));
2137527691bfSHaiyue Wang iavf_print_fdir_fltr(adapter, fdir);
21380dbfbabbSHaiyue Wang }
21390dbfbabbSHaiyue Wang }
21400dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
21410dbfbabbSHaiyue Wang }
21420dbfbabbSHaiyue Wang break;
21430aaeb4fbSHaiyue Wang case VIRTCHNL_OP_ADD_RSS_CFG: {
21440aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss, *rss_tmp;
21450aaeb4fbSHaiyue Wang
21460aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
21470aaeb4fbSHaiyue Wang list_for_each_entry_safe(rss, rss_tmp,
21480aaeb4fbSHaiyue Wang &adapter->adv_rss_list_head,
21490aaeb4fbSHaiyue Wang list) {
21500aaeb4fbSHaiyue Wang if (rss->state == IAVF_ADV_RSS_ADD_PENDING) {
21515ab91e05SHaiyue Wang iavf_print_adv_rss_cfg(adapter, rss,
21525ab91e05SHaiyue Wang "Failed to change the input set for",
21535ab91e05SHaiyue Wang NULL);
21540aaeb4fbSHaiyue Wang list_del(&rss->list);
21550aaeb4fbSHaiyue Wang kfree(rss);
21560aaeb4fbSHaiyue Wang }
21570aaeb4fbSHaiyue Wang }
21580aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
21590aaeb4fbSHaiyue Wang }
21600aaeb4fbSHaiyue Wang break;
21610aaeb4fbSHaiyue Wang case VIRTCHNL_OP_DEL_RSS_CFG: {
21620aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss;
21630aaeb4fbSHaiyue Wang
21640aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
21650aaeb4fbSHaiyue Wang list_for_each_entry(rss, &adapter->adv_rss_list_head,
21660aaeb4fbSHaiyue Wang list) {
21670aaeb4fbSHaiyue Wang if (rss->state == IAVF_ADV_RSS_DEL_PENDING) {
21680aaeb4fbSHaiyue Wang rss->state = IAVF_ADV_RSS_ACTIVE;
21690aaeb4fbSHaiyue Wang dev_err(&adapter->pdev->dev, "Failed to delete RSS configuration, error %s\n",
21700aaeb4fbSHaiyue Wang iavf_stat_str(&adapter->hw,
21710aaeb4fbSHaiyue Wang v_retval));
21720aaeb4fbSHaiyue Wang }
21730aaeb4fbSHaiyue Wang }
21740aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
21750aaeb4fbSHaiyue Wang }
21760aaeb4fbSHaiyue Wang break;
21770dbfbabbSHaiyue Wang case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
21782cf29e55SMichal Maloszewski dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
21792cf29e55SMichal Maloszewski /* Vlan stripping could not be enabled by ethtool.
21802cf29e55SMichal Maloszewski * Disable it in netdev->features.
21812cf29e55SMichal Maloszewski */
21822cf29e55SMichal Maloszewski iavf_netdev_features_vlan_strip_set(netdev, false);
21832cf29e55SMichal Maloszewski break;
21840dbfbabbSHaiyue Wang case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
21850dbfbabbSHaiyue Wang dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
21862cf29e55SMichal Maloszewski /* Vlan stripping could not be disabled by ethtool.
21872cf29e55SMichal Maloszewski * Enable it in netdev->features.
21882cf29e55SMichal Maloszewski */
21892cf29e55SMichal Maloszewski iavf_netdev_features_vlan_strip_set(netdev, true);
21900dbfbabbSHaiyue Wang break;
2191968996c0SPrzemyslaw Patynowski case VIRTCHNL_OP_ADD_VLAN_V2:
2192968996c0SPrzemyslaw Patynowski iavf_vlan_add_reject(adapter);
2193968996c0SPrzemyslaw Patynowski dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
2194968996c0SPrzemyslaw Patynowski iavf_stat_str(&adapter->hw, v_retval));
2195968996c0SPrzemyslaw Patynowski break;
21965ec8b7d1SJesse Brandeburg default:
21975ec8b7d1SJesse Brandeburg dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
21985ec8b7d1SJesse Brandeburg v_retval, iavf_stat_str(&adapter->hw, v_retval),
21995ec8b7d1SJesse Brandeburg v_opcode);
22005ec8b7d1SJesse Brandeburg }
22015ec8b7d1SJesse Brandeburg }
22025ec8b7d1SJesse Brandeburg switch (v_opcode) {
22038da80c9dSSylwester Dziedziuch case VIRTCHNL_OP_ADD_ETH_ADDR:
22048da80c9dSSylwester Dziedziuch if (!v_retval)
22058da80c9dSSylwester Dziedziuch iavf_mac_add_ok(adapter);
2206c5c922b3SStefan Assmann if (!ether_addr_equal(netdev->dev_addr, adapter->hw.mac.addr))
220735a2443dSMateusz Palczewski if (!ether_addr_equal(netdev->dev_addr,
220835a2443dSMateusz Palczewski adapter->hw.mac.addr)) {
220935a2443dSMateusz Palczewski netif_addr_lock_bh(netdev);
2210f3956ebbSJakub Kicinski eth_hw_addr_set(netdev, adapter->hw.mac.addr);
221135a2443dSMateusz Palczewski netif_addr_unlock_bh(netdev);
221235a2443dSMateusz Palczewski }
221335a2443dSMateusz Palczewski wake_up(&adapter->vc_waitqueue);
2214c5c922b3SStefan Assmann break;
22155ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_GET_STATS: {
221656184e01SJesse Brandeburg struct iavf_eth_stats *stats =
221756184e01SJesse Brandeburg (struct iavf_eth_stats *)msg;
22185ec8b7d1SJesse Brandeburg netdev->stats.rx_packets = stats->rx_unicast +
22195ec8b7d1SJesse Brandeburg stats->rx_multicast +
22205ec8b7d1SJesse Brandeburg stats->rx_broadcast;
22215ec8b7d1SJesse Brandeburg netdev->stats.tx_packets = stats->tx_unicast +
22225ec8b7d1SJesse Brandeburg stats->tx_multicast +
22235ec8b7d1SJesse Brandeburg stats->tx_broadcast;
22245ec8b7d1SJesse Brandeburg netdev->stats.rx_bytes = stats->rx_bytes;
22255ec8b7d1SJesse Brandeburg netdev->stats.tx_bytes = stats->tx_bytes;
22265ec8b7d1SJesse Brandeburg netdev->stats.tx_errors = stats->tx_errors;
22275ec8b7d1SJesse Brandeburg netdev->stats.rx_dropped = stats->rx_discards;
22285ec8b7d1SJesse Brandeburg netdev->stats.tx_dropped = stats->tx_discards;
22295ec8b7d1SJesse Brandeburg adapter->current_stats = *stats;
22305ec8b7d1SJesse Brandeburg }
22315ec8b7d1SJesse Brandeburg break;
22325ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_GET_VF_RESOURCES: {
22335e7f59faSAlexander Lobakin u16 len = IAVF_VIRTCHNL_VF_RESOURCE_SIZE;
22345e7f59faSAlexander Lobakin
22355ec8b7d1SJesse Brandeburg memcpy(adapter->vf_res, msg, min(msglen, len));
22365ec8b7d1SJesse Brandeburg iavf_validate_num_queues(adapter);
22375ec8b7d1SJesse Brandeburg iavf_vf_parse_hw_config(&adapter->hw, adapter->vf_res);
22385ec8b7d1SJesse Brandeburg if (is_zero_ether_addr(adapter->hw.mac.addr)) {
22395ec8b7d1SJesse Brandeburg /* restore current mac address */
22405ec8b7d1SJesse Brandeburg ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
22415ec8b7d1SJesse Brandeburg } else {
224235a2443dSMateusz Palczewski netif_addr_lock_bh(netdev);
22435ec8b7d1SJesse Brandeburg /* refresh current mac address if changed */
22445ec8b7d1SJesse Brandeburg ether_addr_copy(netdev->perm_addr,
22455ec8b7d1SJesse Brandeburg adapter->hw.mac.addr);
224635a2443dSMateusz Palczewski netif_addr_unlock_bh(netdev);
22475ec8b7d1SJesse Brandeburg }
22489e052291SStefan Assmann spin_lock_bh(&adapter->mac_vlan_list_lock);
22499e052291SStefan Assmann iavf_add_filter(adapter, adapter->hw.mac.addr);
22505951a2b9SBrett Creeley
22515951a2b9SBrett Creeley if (VLAN_ALLOWED(adapter)) {
22525951a2b9SBrett Creeley if (!list_empty(&adapter->vlan_filter_list)) {
22535951a2b9SBrett Creeley struct iavf_vlan_filter *vlf;
22545951a2b9SBrett Creeley
22555951a2b9SBrett Creeley /* re-add all VLAN filters over virtchnl */
22565951a2b9SBrett Creeley list_for_each_entry(vlf,
22575951a2b9SBrett Creeley &adapter->vlan_filter_list,
22585951a2b9SBrett Creeley list)
22590c0da0e9SAhmed Zaki vlf->state = IAVF_VLAN_ADD;
22605951a2b9SBrett Creeley
22615951a2b9SBrett Creeley adapter->aq_required |=
22625951a2b9SBrett Creeley IAVF_FLAG_AQ_ADD_VLAN_FILTER;
22635951a2b9SBrett Creeley }
22645951a2b9SBrett Creeley }
22655951a2b9SBrett Creeley
22669e052291SStefan Assmann spin_unlock_bh(&adapter->mac_vlan_list_lock);
2267209f2f9cSBrett Creeley
2268*3beb9d66SPiotr Gardocki iavf_activate_fdir_filters(adapter);
2269*3beb9d66SPiotr Gardocki
2270209f2f9cSBrett Creeley iavf_parse_vf_resource_msg(adapter);
2271209f2f9cSBrett Creeley
2272209f2f9cSBrett Creeley /* negotiated VIRTCHNL_VF_OFFLOAD_VLAN_V2, so wait for the
2273209f2f9cSBrett Creeley * response to VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS to finish
2274209f2f9cSBrett Creeley * configuration
2275209f2f9cSBrett Creeley */
2276209f2f9cSBrett Creeley if (VLAN_V2_ALLOWED(adapter))
2277209f2f9cSBrett Creeley break;
2278209f2f9cSBrett Creeley /* fallthrough and finish config if VIRTCHNL_VF_OFFLOAD_VLAN_V2
2279209f2f9cSBrett Creeley * wasn't successfully negotiated with the PF
2280209f2f9cSBrett Creeley */
2281209f2f9cSBrett Creeley }
2282209f2f9cSBrett Creeley fallthrough;
2283209f2f9cSBrett Creeley case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS: {
228435a2443dSMateusz Palczewski struct iavf_mac_filter *f;
228535a2443dSMateusz Palczewski bool was_mac_changed;
228635a2443dSMateusz Palczewski u64 aq_required = 0;
228735a2443dSMateusz Palczewski
2288209f2f9cSBrett Creeley if (v_opcode == VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS)
2289209f2f9cSBrett Creeley memcpy(&adapter->vlan_v2_caps, msg,
2290209f2f9cSBrett Creeley min_t(u16, msglen,
2291209f2f9cSBrett Creeley sizeof(adapter->vlan_v2_caps)));
2292209f2f9cSBrett Creeley
22935ec8b7d1SJesse Brandeburg iavf_process_config(adapter);
22940579fafdSSlawomir Laba adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES;
2295d1639a17SAhmed Zaki iavf_schedule_finish_config(adapter);
22967598f4b4SMarcin Szycik
22977598f4b4SMarcin Szycik iavf_set_queue_vlan_tag_loc(adapter);
22987598f4b4SMarcin Szycik
229935a2443dSMateusz Palczewski was_mac_changed = !ether_addr_equal(netdev->dev_addr,
230035a2443dSMateusz Palczewski adapter->hw.mac.addr);
230135a2443dSMateusz Palczewski
230235a2443dSMateusz Palczewski spin_lock_bh(&adapter->mac_vlan_list_lock);
230335a2443dSMateusz Palczewski
230435a2443dSMateusz Palczewski /* re-add all MAC filters */
230535a2443dSMateusz Palczewski list_for_each_entry(f, &adapter->mac_filter_list, list) {
230635a2443dSMateusz Palczewski if (was_mac_changed &&
230735a2443dSMateusz Palczewski ether_addr_equal(netdev->dev_addr, f->macaddr))
230835a2443dSMateusz Palczewski ether_addr_copy(f->macaddr,
230935a2443dSMateusz Palczewski adapter->hw.mac.addr);
231035a2443dSMateusz Palczewski
231135a2443dSMateusz Palczewski f->is_new_mac = true;
231235a2443dSMateusz Palczewski f->add = true;
231335a2443dSMateusz Palczewski f->add_handled = false;
231435a2443dSMateusz Palczewski f->remove = false;
231535a2443dSMateusz Palczewski }
231635a2443dSMateusz Palczewski
231735a2443dSMateusz Palczewski /* re-add all VLAN filters */
231835a2443dSMateusz Palczewski if (VLAN_FILTERING_ALLOWED(adapter)) {
231935a2443dSMateusz Palczewski struct iavf_vlan_filter *vlf;
232035a2443dSMateusz Palczewski
232135a2443dSMateusz Palczewski if (!list_empty(&adapter->vlan_filter_list)) {
232235a2443dSMateusz Palczewski list_for_each_entry(vlf,
232335a2443dSMateusz Palczewski &adapter->vlan_filter_list,
232435a2443dSMateusz Palczewski list)
23250c0da0e9SAhmed Zaki vlf->state = IAVF_VLAN_ADD;
232635a2443dSMateusz Palczewski
232735a2443dSMateusz Palczewski aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
232835a2443dSMateusz Palczewski }
232935a2443dSMateusz Palczewski }
233035a2443dSMateusz Palczewski
233135a2443dSMateusz Palczewski spin_unlock_bh(&adapter->mac_vlan_list_lock);
233235a2443dSMateusz Palczewski
233335a2443dSMateusz Palczewski netif_addr_lock_bh(netdev);
233435a2443dSMateusz Palczewski eth_hw_addr_set(netdev, adapter->hw.mac.addr);
233535a2443dSMateusz Palczewski netif_addr_unlock_bh(netdev);
233635a2443dSMateusz Palczewski
233735a2443dSMateusz Palczewski adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER |
233835a2443dSMateusz Palczewski aq_required;
23395ec8b7d1SJesse Brandeburg }
23405ec8b7d1SJesse Brandeburg break;
23415ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ENABLE_QUEUES:
23425ec8b7d1SJesse Brandeburg /* enable transmits */
23435ec8b7d1SJesse Brandeburg iavf_irq_enable(adapter, true);
2344c2ed2403SMarcin Szycik wake_up(&adapter->reset_waitqueue);
23455ec8b7d1SJesse Brandeburg adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED;
23465ec8b7d1SJesse Brandeburg break;
23475ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DISABLE_QUEUES:
23485ec8b7d1SJesse Brandeburg iavf_free_all_tx_resources(adapter);
23495ec8b7d1SJesse Brandeburg iavf_free_all_rx_resources(adapter);
23505ec8b7d1SJesse Brandeburg if (adapter->state == __IAVF_DOWN_PENDING) {
235145eebd62SMateusz Palczewski iavf_change_state(adapter, __IAVF_DOWN);
23525ec8b7d1SJesse Brandeburg wake_up(&adapter->down_waitqueue);
23535ec8b7d1SJesse Brandeburg }
23545ec8b7d1SJesse Brandeburg break;
23555ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_VERSION:
23565ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_CONFIG_IRQ_MAP:
23575ec8b7d1SJesse Brandeburg /* Don't display an error if we get these out of sequence.
23585ec8b7d1SJesse Brandeburg * If the firmware needed to get kicked, we'll get these and
23595ec8b7d1SJesse Brandeburg * it's no problem.
23605ec8b7d1SJesse Brandeburg */
23615ec8b7d1SJesse Brandeburg if (v_opcode != adapter->current_op)
23625ec8b7d1SJesse Brandeburg return;
23635ec8b7d1SJesse Brandeburg break;
23642723f3b5SJesse Brandeburg case VIRTCHNL_OP_RDMA:
23655ec8b7d1SJesse Brandeburg /* Gobble zero-length replies from the PF. They indicate that
23665ec8b7d1SJesse Brandeburg * a previous message was received OK, and the client doesn't
23675ec8b7d1SJesse Brandeburg * care about that.
23685ec8b7d1SJesse Brandeburg */
23695ec8b7d1SJesse Brandeburg if (msglen && CLIENT_ENABLED(adapter))
23705ec8b7d1SJesse Brandeburg iavf_notify_client_message(&adapter->vsi, msg, msglen);
23715ec8b7d1SJesse Brandeburg break;
23725ec8b7d1SJesse Brandeburg
23732723f3b5SJesse Brandeburg case VIRTCHNL_OP_CONFIG_RDMA_IRQ_MAP:
23745ec8b7d1SJesse Brandeburg adapter->client_pending &=
23752723f3b5SJesse Brandeburg ~(BIT(VIRTCHNL_OP_CONFIG_RDMA_IRQ_MAP));
23765ec8b7d1SJesse Brandeburg break;
23775ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_GET_RSS_HENA_CAPS: {
23785ec8b7d1SJesse Brandeburg struct virtchnl_rss_hena *vrh = (struct virtchnl_rss_hena *)msg;
23795ec8b7d1SJesse Brandeburg
23805ec8b7d1SJesse Brandeburg if (msglen == sizeof(*vrh))
23815ec8b7d1SJesse Brandeburg adapter->hena = vrh->hena;
23825ec8b7d1SJesse Brandeburg else
23835ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev,
23845ec8b7d1SJesse Brandeburg "Invalid message %d from PF\n", v_opcode);
23855ec8b7d1SJesse Brandeburg }
23865ec8b7d1SJesse Brandeburg break;
23875ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_REQUEST_QUEUES: {
23885ec8b7d1SJesse Brandeburg struct virtchnl_vf_res_request *vfres =
23895ec8b7d1SJesse Brandeburg (struct virtchnl_vf_res_request *)msg;
23905ec8b7d1SJesse Brandeburg
23915ec8b7d1SJesse Brandeburg if (vfres->num_queue_pairs != adapter->num_req_queues) {
23925ec8b7d1SJesse Brandeburg dev_info(&adapter->pdev->dev,
23935ec8b7d1SJesse Brandeburg "Requested %d queues, PF can support %d\n",
23945ec8b7d1SJesse Brandeburg adapter->num_req_queues,
23955ec8b7d1SJesse Brandeburg vfres->num_queue_pairs);
23965ec8b7d1SJesse Brandeburg adapter->num_req_queues = 0;
23975ec8b7d1SJesse Brandeburg adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
23985ec8b7d1SJesse Brandeburg }
23995ec8b7d1SJesse Brandeburg }
24005ec8b7d1SJesse Brandeburg break;
24015ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
24025ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf;
24035ec8b7d1SJesse Brandeburg
24045ec8b7d1SJesse Brandeburg list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
24055ec8b7d1SJesse Brandeburg if (cf->state == __IAVF_CF_ADD_PENDING)
24065ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_ACTIVE;
24075ec8b7d1SJesse Brandeburg }
24085ec8b7d1SJesse Brandeburg }
24095ec8b7d1SJesse Brandeburg break;
24105ec8b7d1SJesse Brandeburg case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
24115ec8b7d1SJesse Brandeburg struct iavf_cloud_filter *cf, *cftmp;
24125ec8b7d1SJesse Brandeburg
24135ec8b7d1SJesse Brandeburg list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
24145ec8b7d1SJesse Brandeburg list) {
24155ec8b7d1SJesse Brandeburg if (cf->state == __IAVF_CF_DEL_PENDING) {
24165ec8b7d1SJesse Brandeburg cf->state = __IAVF_CF_INVALID;
24175ec8b7d1SJesse Brandeburg list_del(&cf->list);
24185ec8b7d1SJesse Brandeburg kfree(cf);
24195ec8b7d1SJesse Brandeburg adapter->num_cloud_filters--;
24205ec8b7d1SJesse Brandeburg }
24215ec8b7d1SJesse Brandeburg }
24225ec8b7d1SJesse Brandeburg }
24235ec8b7d1SJesse Brandeburg break;
24240dbfbabbSHaiyue Wang case VIRTCHNL_OP_ADD_FDIR_FILTER: {
24250dbfbabbSHaiyue Wang struct virtchnl_fdir_add *add_fltr = (struct virtchnl_fdir_add *)msg;
24260dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir, *fdir_tmp;
24270dbfbabbSHaiyue Wang
24280dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
24290dbfbabbSHaiyue Wang list_for_each_entry_safe(fdir, fdir_tmp,
24300dbfbabbSHaiyue Wang &adapter->fdir_list_head,
24310dbfbabbSHaiyue Wang list) {
24320dbfbabbSHaiyue Wang if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING) {
24330dbfbabbSHaiyue Wang if (add_fltr->status == VIRTCHNL_FDIR_SUCCESS) {
2434527691bfSHaiyue Wang dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is added\n",
2435527691bfSHaiyue Wang fdir->loc);
24360dbfbabbSHaiyue Wang fdir->state = IAVF_FDIR_FLTR_ACTIVE;
24370dbfbabbSHaiyue Wang fdir->flow_id = add_fltr->flow_id;
24380dbfbabbSHaiyue Wang } else {
24390dbfbabbSHaiyue Wang dev_info(&adapter->pdev->dev, "Failed to add Flow Director filter with status: %d\n",
24400dbfbabbSHaiyue Wang add_fltr->status);
2441527691bfSHaiyue Wang iavf_print_fdir_fltr(adapter, fdir);
24420dbfbabbSHaiyue Wang list_del(&fdir->list);
24430dbfbabbSHaiyue Wang kfree(fdir);
24440dbfbabbSHaiyue Wang adapter->fdir_active_fltr--;
24450dbfbabbSHaiyue Wang }
24460dbfbabbSHaiyue Wang }
24470dbfbabbSHaiyue Wang }
24480dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
24490dbfbabbSHaiyue Wang }
24500dbfbabbSHaiyue Wang break;
24510dbfbabbSHaiyue Wang case VIRTCHNL_OP_DEL_FDIR_FILTER: {
24520dbfbabbSHaiyue Wang struct virtchnl_fdir_del *del_fltr = (struct virtchnl_fdir_del *)msg;
24530dbfbabbSHaiyue Wang struct iavf_fdir_fltr *fdir, *fdir_tmp;
24540dbfbabbSHaiyue Wang
24550dbfbabbSHaiyue Wang spin_lock_bh(&adapter->fdir_fltr_lock);
24560dbfbabbSHaiyue Wang list_for_each_entry_safe(fdir, fdir_tmp, &adapter->fdir_list_head,
24570dbfbabbSHaiyue Wang list) {
24580dbfbabbSHaiyue Wang if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) {
2459*3beb9d66SPiotr Gardocki if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS ||
2460*3beb9d66SPiotr Gardocki del_fltr->status ==
2461*3beb9d66SPiotr Gardocki VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
2462527691bfSHaiyue Wang dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is deleted\n",
2463527691bfSHaiyue Wang fdir->loc);
24640dbfbabbSHaiyue Wang list_del(&fdir->list);
24650dbfbabbSHaiyue Wang kfree(fdir);
24660dbfbabbSHaiyue Wang adapter->fdir_active_fltr--;
24670dbfbabbSHaiyue Wang } else {
24680dbfbabbSHaiyue Wang fdir->state = IAVF_FDIR_FLTR_ACTIVE;
24690dbfbabbSHaiyue Wang dev_info(&adapter->pdev->dev, "Failed to delete Flow Director filter with status: %d\n",
24700dbfbabbSHaiyue Wang del_fltr->status);
2471527691bfSHaiyue Wang iavf_print_fdir_fltr(adapter, fdir);
24720dbfbabbSHaiyue Wang }
2473*3beb9d66SPiotr Gardocki } else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) {
2474*3beb9d66SPiotr Gardocki if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS ||
2475*3beb9d66SPiotr Gardocki del_fltr->status ==
2476*3beb9d66SPiotr Gardocki VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
2477*3beb9d66SPiotr Gardocki fdir->state = IAVF_FDIR_FLTR_INACTIVE;
2478*3beb9d66SPiotr Gardocki } else {
2479*3beb9d66SPiotr Gardocki fdir->state = IAVF_FDIR_FLTR_ACTIVE;
2480*3beb9d66SPiotr Gardocki dev_info(&adapter->pdev->dev, "Failed to disable Flow Director filter with status: %d\n",
2481*3beb9d66SPiotr Gardocki del_fltr->status);
2482*3beb9d66SPiotr Gardocki iavf_print_fdir_fltr(adapter, fdir);
2483*3beb9d66SPiotr Gardocki }
24840dbfbabbSHaiyue Wang }
24850dbfbabbSHaiyue Wang }
24860dbfbabbSHaiyue Wang spin_unlock_bh(&adapter->fdir_fltr_lock);
24870dbfbabbSHaiyue Wang }
24880dbfbabbSHaiyue Wang break;
24890aaeb4fbSHaiyue Wang case VIRTCHNL_OP_ADD_RSS_CFG: {
24900aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss;
24910aaeb4fbSHaiyue Wang
24920aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
24935ab91e05SHaiyue Wang list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
24945ab91e05SHaiyue Wang if (rss->state == IAVF_ADV_RSS_ADD_PENDING) {
24955ab91e05SHaiyue Wang iavf_print_adv_rss_cfg(adapter, rss,
24965ab91e05SHaiyue Wang "Input set change for",
24975ab91e05SHaiyue Wang "successful");
24980aaeb4fbSHaiyue Wang rss->state = IAVF_ADV_RSS_ACTIVE;
24995ab91e05SHaiyue Wang }
25005ab91e05SHaiyue Wang }
25010aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
25020aaeb4fbSHaiyue Wang }
25030aaeb4fbSHaiyue Wang break;
25040aaeb4fbSHaiyue Wang case VIRTCHNL_OP_DEL_RSS_CFG: {
25050aaeb4fbSHaiyue Wang struct iavf_adv_rss *rss, *rss_tmp;
25060aaeb4fbSHaiyue Wang
25070aaeb4fbSHaiyue Wang spin_lock_bh(&adapter->adv_rss_lock);
25080aaeb4fbSHaiyue Wang list_for_each_entry_safe(rss, rss_tmp,
25090aaeb4fbSHaiyue Wang &adapter->adv_rss_list_head, list) {
25100aaeb4fbSHaiyue Wang if (rss->state == IAVF_ADV_RSS_DEL_PENDING) {
25110aaeb4fbSHaiyue Wang list_del(&rss->list);
25120aaeb4fbSHaiyue Wang kfree(rss);
25130aaeb4fbSHaiyue Wang }
25140aaeb4fbSHaiyue Wang }
25150aaeb4fbSHaiyue Wang spin_unlock_bh(&adapter->adv_rss_lock);
25160aaeb4fbSHaiyue Wang }
25170aaeb4fbSHaiyue Wang break;
2518968996c0SPrzemyslaw Patynowski case VIRTCHNL_OP_ADD_VLAN_V2: {
2519968996c0SPrzemyslaw Patynowski struct iavf_vlan_filter *f;
2520968996c0SPrzemyslaw Patynowski
2521968996c0SPrzemyslaw Patynowski spin_lock_bh(&adapter->mac_vlan_list_lock);
2522968996c0SPrzemyslaw Patynowski list_for_each_entry(f, &adapter->vlan_filter_list, list) {
25239c85b7faSAhmed Zaki if (f->state == IAVF_VLAN_IS_NEW)
25240c0da0e9SAhmed Zaki f->state = IAVF_VLAN_ACTIVE;
2525968996c0SPrzemyslaw Patynowski }
2526968996c0SPrzemyslaw Patynowski spin_unlock_bh(&adapter->mac_vlan_list_lock);
2527968996c0SPrzemyslaw Patynowski }
2528968996c0SPrzemyslaw Patynowski break;
25292cf29e55SMichal Maloszewski case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
25302cf29e55SMichal Maloszewski /* PF enabled vlan strip on this VF.
25312cf29e55SMichal Maloszewski * Update netdev->features if needed to be in sync with ethtool.
25322cf29e55SMichal Maloszewski */
25332cf29e55SMichal Maloszewski if (!v_retval)
25342cf29e55SMichal Maloszewski iavf_netdev_features_vlan_strip_set(netdev, true);
25352cf29e55SMichal Maloszewski break;
25362cf29e55SMichal Maloszewski case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
25372cf29e55SMichal Maloszewski /* PF disabled vlan strip on this VF.
25382cf29e55SMichal Maloszewski * Update netdev->features if needed to be in sync with ethtool.
25392cf29e55SMichal Maloszewski */
25402cf29e55SMichal Maloszewski if (!v_retval)
25412cf29e55SMichal Maloszewski iavf_netdev_features_vlan_strip_set(netdev, false);
25422cf29e55SMichal Maloszewski break;
25435ec8b7d1SJesse Brandeburg default:
25445ec8b7d1SJesse Brandeburg if (adapter->current_op && (v_opcode != adapter->current_op))
25455ec8b7d1SJesse Brandeburg dev_warn(&adapter->pdev->dev, "Expected response %d from PF, received %d\n",
25465ec8b7d1SJesse Brandeburg adapter->current_op, v_opcode);
25475ec8b7d1SJesse Brandeburg break;
25485ec8b7d1SJesse Brandeburg } /* switch v_opcode */
25495ec8b7d1SJesse Brandeburg adapter->current_op = VIRTCHNL_OP_UNKNOWN;
25505ec8b7d1SJesse Brandeburg }
2551