1109aba47SJacob Keller // SPDX-License-Identifier: GPL-2.0
2109aba47SJacob Keller /* Copyright (C) 2022, Intel Corporation. */
3109aba47SJacob Keller 
4109aba47SJacob Keller #include "ice_vf_lib_private.h"
5109aba47SJacob Keller #include "ice.h"
6109aba47SJacob Keller #include "ice_lib.h"
7109aba47SJacob Keller #include "ice_fltr.h"
8109aba47SJacob Keller #include "ice_virtchnl_allowlist.h"
9109aba47SJacob Keller 
10109aba47SJacob Keller /* Public functions which may be accessed by all driver files */
11109aba47SJacob Keller 
12109aba47SJacob Keller /**
13109aba47SJacob Keller  * ice_get_vf_by_id - Get pointer to VF by ID
14109aba47SJacob Keller  * @pf: the PF private structure
15109aba47SJacob Keller  * @vf_id: the VF ID to locate
16109aba47SJacob Keller  *
17109aba47SJacob Keller  * Locate and return a pointer to the VF structure associated with a given ID.
18109aba47SJacob Keller  * Returns NULL if the ID does not have a valid VF structure associated with
19109aba47SJacob Keller  * it.
20109aba47SJacob Keller  *
21109aba47SJacob Keller  * This function takes a reference to the VF, which must be released by
22109aba47SJacob Keller  * calling ice_put_vf() once the caller is finished accessing the VF structure
23109aba47SJacob Keller  * returned.
24109aba47SJacob Keller  */
25109aba47SJacob Keller struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id)
26109aba47SJacob Keller {
27109aba47SJacob Keller 	struct ice_vf *vf;
28109aba47SJacob Keller 
29109aba47SJacob Keller 	rcu_read_lock();
30109aba47SJacob Keller 	hash_for_each_possible_rcu(pf->vfs.table, vf, entry, vf_id) {
31109aba47SJacob Keller 		if (vf->vf_id == vf_id) {
32109aba47SJacob Keller 			struct ice_vf *found;
33109aba47SJacob Keller 
34109aba47SJacob Keller 			if (kref_get_unless_zero(&vf->refcnt))
35109aba47SJacob Keller 				found = vf;
36109aba47SJacob Keller 			else
37109aba47SJacob Keller 				found = NULL;
38109aba47SJacob Keller 
39109aba47SJacob Keller 			rcu_read_unlock();
40109aba47SJacob Keller 			return found;
41109aba47SJacob Keller 		}
42109aba47SJacob Keller 	}
43109aba47SJacob Keller 	rcu_read_unlock();
44109aba47SJacob Keller 
45109aba47SJacob Keller 	return NULL;
46109aba47SJacob Keller }
47109aba47SJacob Keller 
48109aba47SJacob Keller /**
49109aba47SJacob Keller  * ice_release_vf - Release VF associated with a refcount
50109aba47SJacob Keller  * @ref: the kref decremented to zero
51109aba47SJacob Keller  *
52109aba47SJacob Keller  * Callback function for kref_put to release a VF once its reference count has
53109aba47SJacob Keller  * hit zero.
54109aba47SJacob Keller  */
55109aba47SJacob Keller static void ice_release_vf(struct kref *ref)
56109aba47SJacob Keller {
57109aba47SJacob Keller 	struct ice_vf *vf = container_of(ref, struct ice_vf, refcnt);
58109aba47SJacob Keller 
599c6f7878SJacob Keller 	vf->vf_ops->free(vf);
60109aba47SJacob Keller }
61109aba47SJacob Keller 
62109aba47SJacob Keller /**
63109aba47SJacob Keller  * ice_put_vf - Release a reference to a VF
64109aba47SJacob Keller  * @vf: the VF structure to decrease reference count on
65109aba47SJacob Keller  *
66109aba47SJacob Keller  * Decrease the reference count for a VF, and free the entry if it is no
67109aba47SJacob Keller  * longer in use.
68109aba47SJacob Keller  *
69109aba47SJacob Keller  * This must be called after ice_get_vf_by_id() once the reference to the VF
70109aba47SJacob Keller  * structure is no longer used. Otherwise, the VF structure will never be
71109aba47SJacob Keller  * freed.
72109aba47SJacob Keller  */
73109aba47SJacob Keller void ice_put_vf(struct ice_vf *vf)
74109aba47SJacob Keller {
75109aba47SJacob Keller 	kref_put(&vf->refcnt, ice_release_vf);
76109aba47SJacob Keller }
77109aba47SJacob Keller 
78109aba47SJacob Keller /**
79109aba47SJacob Keller  * ice_has_vfs - Return true if the PF has any associated VFs
80109aba47SJacob Keller  * @pf: the PF private structure
81109aba47SJacob Keller  *
82109aba47SJacob Keller  * Return whether or not the PF has any allocated VFs.
83109aba47SJacob Keller  *
84109aba47SJacob Keller  * Note that this function only guarantees that there are no VFs at the point
85109aba47SJacob Keller  * of calling it. It does not guarantee that no more VFs will be added.
86109aba47SJacob Keller  */
87109aba47SJacob Keller bool ice_has_vfs(struct ice_pf *pf)
88109aba47SJacob Keller {
89109aba47SJacob Keller 	/* A simple check that the hash table is not empty does not require
90109aba47SJacob Keller 	 * the mutex or rcu_read_lock.
91109aba47SJacob Keller 	 */
92109aba47SJacob Keller 	return !hash_empty(pf->vfs.table);
93109aba47SJacob Keller }
94109aba47SJacob Keller 
95109aba47SJacob Keller /**
96109aba47SJacob Keller  * ice_get_num_vfs - Get number of allocated VFs
97109aba47SJacob Keller  * @pf: the PF private structure
98109aba47SJacob Keller  *
99109aba47SJacob Keller  * Return the total number of allocated VFs. NOTE: VF IDs are not guaranteed
100109aba47SJacob Keller  * to be contiguous. Do not assume that a VF ID is guaranteed to be less than
101109aba47SJacob Keller  * the output of this function.
102109aba47SJacob Keller  */
103109aba47SJacob Keller u16 ice_get_num_vfs(struct ice_pf *pf)
104109aba47SJacob Keller {
105109aba47SJacob Keller 	struct ice_vf *vf;
106109aba47SJacob Keller 	unsigned int bkt;
107109aba47SJacob Keller 	u16 num_vfs = 0;
108109aba47SJacob Keller 
109109aba47SJacob Keller 	rcu_read_lock();
110109aba47SJacob Keller 	ice_for_each_vf_rcu(pf, bkt, vf)
111109aba47SJacob Keller 		num_vfs++;
112109aba47SJacob Keller 	rcu_read_unlock();
113109aba47SJacob Keller 
114109aba47SJacob Keller 	return num_vfs;
115109aba47SJacob Keller }
116109aba47SJacob Keller 
117109aba47SJacob Keller /**
118109aba47SJacob Keller  * ice_get_vf_vsi - get VF's VSI based on the stored index
119109aba47SJacob Keller  * @vf: VF used to get VSI
120109aba47SJacob Keller  */
121109aba47SJacob Keller struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf)
122109aba47SJacob Keller {
123109aba47SJacob Keller 	if (vf->lan_vsi_idx == ICE_NO_VSI)
124109aba47SJacob Keller 		return NULL;
125109aba47SJacob Keller 
126109aba47SJacob Keller 	return vf->pf->vsi[vf->lan_vsi_idx];
127109aba47SJacob Keller }
128109aba47SJacob Keller 
129109aba47SJacob Keller /**
130109aba47SJacob Keller  * ice_is_vf_disabled
131109aba47SJacob Keller  * @vf: pointer to the VF info
132109aba47SJacob Keller  *
133109aba47SJacob Keller  * If the PF has been disabled, there is no need resetting VF until PF is
134109aba47SJacob Keller  * active again. Similarly, if the VF has been disabled, this means something
135109aba47SJacob Keller  * else is resetting the VF, so we shouldn't continue.
136109aba47SJacob Keller  *
137109aba47SJacob Keller  * Returns true if the caller should consider the VF as disabled whether
138109aba47SJacob Keller  * because that single VF is explicitly disabled or because the PF is
139109aba47SJacob Keller  * currently disabled.
140109aba47SJacob Keller  */
141109aba47SJacob Keller bool ice_is_vf_disabled(struct ice_vf *vf)
142109aba47SJacob Keller {
143109aba47SJacob Keller 	struct ice_pf *pf = vf->pf;
144109aba47SJacob Keller 
145109aba47SJacob Keller 	return (test_bit(ICE_VF_DIS, pf->state) ||
146109aba47SJacob Keller 		test_bit(ICE_VF_STATE_DIS, vf->vf_states));
147109aba47SJacob Keller }
148109aba47SJacob Keller 
149109aba47SJacob Keller /**
150109aba47SJacob Keller  * ice_wait_on_vf_reset - poll to make sure a given VF is ready after reset
151109aba47SJacob Keller  * @vf: The VF being resseting
152109aba47SJacob Keller  *
153109aba47SJacob Keller  * The max poll time is about ~800ms, which is about the maximum time it takes
154109aba47SJacob Keller  * for a VF to be reset and/or a VF driver to be removed.
155109aba47SJacob Keller  */
156109aba47SJacob Keller static void ice_wait_on_vf_reset(struct ice_vf *vf)
157109aba47SJacob Keller {
158109aba47SJacob Keller 	int i;
159109aba47SJacob Keller 
160109aba47SJacob Keller 	for (i = 0; i < ICE_MAX_VF_RESET_TRIES; i++) {
161109aba47SJacob Keller 		if (test_bit(ICE_VF_STATE_INIT, vf->vf_states))
162109aba47SJacob Keller 			break;
163109aba47SJacob Keller 		msleep(ICE_MAX_VF_RESET_SLEEP_MS);
164109aba47SJacob Keller 	}
165109aba47SJacob Keller }
166109aba47SJacob Keller 
167109aba47SJacob Keller /**
168109aba47SJacob Keller  * ice_check_vf_ready_for_cfg - check if VF is ready to be configured/queried
169109aba47SJacob Keller  * @vf: VF to check if it's ready to be configured/queried
170109aba47SJacob Keller  *
171109aba47SJacob Keller  * The purpose of this function is to make sure the VF is not in reset, not
172109aba47SJacob Keller  * disabled, and initialized so it can be configured and/or queried by a host
173109aba47SJacob Keller  * administrator.
174109aba47SJacob Keller  */
175109aba47SJacob Keller int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
176109aba47SJacob Keller {
177109aba47SJacob Keller 	ice_wait_on_vf_reset(vf);
178109aba47SJacob Keller 
179109aba47SJacob Keller 	if (ice_is_vf_disabled(vf))
180109aba47SJacob Keller 		return -EINVAL;
181109aba47SJacob Keller 
1825a57ee83SJacob Keller 	if (ice_check_vf_init(vf))
183109aba47SJacob Keller 		return -EBUSY;
184109aba47SJacob Keller 
185109aba47SJacob Keller 	return 0;
186109aba47SJacob Keller }
187109aba47SJacob Keller 
188109aba47SJacob Keller /**
18916686d7fSJacob Keller  * ice_trigger_vf_reset - Reset a VF on HW
19016686d7fSJacob Keller  * @vf: pointer to the VF structure
19116686d7fSJacob Keller  * @is_vflr: true if VFLR was issued, false if not
19216686d7fSJacob Keller  * @is_pfr: true if the reset was triggered due to a previous PFR
19316686d7fSJacob Keller  *
19416686d7fSJacob Keller  * Trigger hardware to start a reset for a particular VF. Expects the caller
19516686d7fSJacob Keller  * to wait the proper amount of time to allow hardware to reset the VF before
19616686d7fSJacob Keller  * it cleans up and restores VF functionality.
19716686d7fSJacob Keller  */
19816686d7fSJacob Keller static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr)
19916686d7fSJacob Keller {
20016686d7fSJacob Keller 	/* Inform VF that it is no longer active, as a warning */
20116686d7fSJacob Keller 	clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
20216686d7fSJacob Keller 
20316686d7fSJacob Keller 	/* Disable VF's configuration API during reset. The flag is re-enabled
20416686d7fSJacob Keller 	 * when it's safe again to access VF's VSI.
20516686d7fSJacob Keller 	 */
20616686d7fSJacob Keller 	clear_bit(ICE_VF_STATE_INIT, vf->vf_states);
20716686d7fSJacob Keller 
20816686d7fSJacob Keller 	/* VF_MBX_ARQLEN and VF_MBX_ATQLEN are cleared by PFR, so the driver
20916686d7fSJacob Keller 	 * needs to clear them in the case of VFR/VFLR. If this is done for
21016686d7fSJacob Keller 	 * PFR, it can mess up VF resets because the VF driver may already
21116686d7fSJacob Keller 	 * have started cleanup by the time we get here.
21216686d7fSJacob Keller 	 */
21316686d7fSJacob Keller 	if (!is_pfr)
21416686d7fSJacob Keller 		vf->vf_ops->clear_mbx_register(vf);
21516686d7fSJacob Keller 
21616686d7fSJacob Keller 	vf->vf_ops->trigger_reset_register(vf, is_vflr);
21716686d7fSJacob Keller }
21816686d7fSJacob Keller 
21916686d7fSJacob Keller static void ice_vf_clear_counters(struct ice_vf *vf)
22016686d7fSJacob Keller {
22116686d7fSJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
22216686d7fSJacob Keller 
223baeb705fSJacob Keller 	if (vsi)
22416686d7fSJacob Keller 		vsi->num_vlan = 0;
225baeb705fSJacob Keller 
226baeb705fSJacob Keller 	vf->num_mac = 0;
22716686d7fSJacob Keller 	memset(&vf->mdd_tx_events, 0, sizeof(vf->mdd_tx_events));
22816686d7fSJacob Keller 	memset(&vf->mdd_rx_events, 0, sizeof(vf->mdd_rx_events));
22916686d7fSJacob Keller }
23016686d7fSJacob Keller 
23116686d7fSJacob Keller /**
23216686d7fSJacob Keller  * ice_vf_pre_vsi_rebuild - tasks to be done prior to VSI rebuild
23316686d7fSJacob Keller  * @vf: VF to perform pre VSI rebuild tasks
23416686d7fSJacob Keller  *
23516686d7fSJacob Keller  * These tasks are items that don't need to be amortized since they are most
23616686d7fSJacob Keller  * likely called in a for loop with all VF(s) in the reset_all_vfs() case.
23716686d7fSJacob Keller  */
23816686d7fSJacob Keller static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf)
23916686d7fSJacob Keller {
24016686d7fSJacob Keller 	ice_vf_clear_counters(vf);
24116686d7fSJacob Keller 	vf->vf_ops->clear_reset_trigger(vf);
24216686d7fSJacob Keller }
24316686d7fSJacob Keller 
24416686d7fSJacob Keller /**
24516686d7fSJacob Keller  * ice_vf_rebuild_vsi - rebuild the VF's VSI
24616686d7fSJacob Keller  * @vf: VF to rebuild the VSI for
24716686d7fSJacob Keller  *
24816686d7fSJacob Keller  * This is only called when all VF(s) are being reset (i.e. PCIe Reset on the
24916686d7fSJacob Keller  * host, PFR, CORER, etc.).
25016686d7fSJacob Keller  */
25116686d7fSJacob Keller static int ice_vf_rebuild_vsi(struct ice_vf *vf)
25216686d7fSJacob Keller {
25316686d7fSJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
25416686d7fSJacob Keller 	struct ice_pf *pf = vf->pf;
25516686d7fSJacob Keller 
256baeb705fSJacob Keller 	if (WARN_ON(!vsi))
257baeb705fSJacob Keller 		return -EINVAL;
258baeb705fSJacob Keller 
25916686d7fSJacob Keller 	if (ice_vsi_rebuild(vsi, true)) {
26016686d7fSJacob Keller 		dev_err(ice_pf_to_dev(pf), "failed to rebuild VF %d VSI\n",
26116686d7fSJacob Keller 			vf->vf_id);
26216686d7fSJacob Keller 		return -EIO;
26316686d7fSJacob Keller 	}
26416686d7fSJacob Keller 	/* vsi->idx will remain the same in this case so don't update
26516686d7fSJacob Keller 	 * vf->lan_vsi_idx
26616686d7fSJacob Keller 	 */
26716686d7fSJacob Keller 	vsi->vsi_num = ice_get_hw_vsi_num(&pf->hw, vsi->idx);
26816686d7fSJacob Keller 	vf->lan_vsi_num = vsi->vsi_num;
26916686d7fSJacob Keller 
27016686d7fSJacob Keller 	return 0;
27116686d7fSJacob Keller }
27216686d7fSJacob Keller 
27316686d7fSJacob Keller /**
274*d7393425SMichal Wilczynski  * ice_is_any_vf_in_unicast_promisc - check if any VF(s)
275*d7393425SMichal Wilczynski  * are in unicast promiscuous mode
276109aba47SJacob Keller  * @pf: PF structure for accessing VF(s)
277109aba47SJacob Keller  *
278*d7393425SMichal Wilczynski  * Return false if no VF(s) are in unicast promiscuous mode,
279109aba47SJacob Keller  * else return true
280109aba47SJacob Keller  */
281*d7393425SMichal Wilczynski bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf)
282109aba47SJacob Keller {
283109aba47SJacob Keller 	bool is_vf_promisc = false;
284109aba47SJacob Keller 	struct ice_vf *vf;
285109aba47SJacob Keller 	unsigned int bkt;
286109aba47SJacob Keller 
287109aba47SJacob Keller 	rcu_read_lock();
288109aba47SJacob Keller 	ice_for_each_vf_rcu(pf, bkt, vf) {
289109aba47SJacob Keller 		/* found a VF that has promiscuous mode configured */
290*d7393425SMichal Wilczynski 		if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) {
291109aba47SJacob Keller 			is_vf_promisc = true;
292109aba47SJacob Keller 			break;
293109aba47SJacob Keller 		}
294109aba47SJacob Keller 	}
295109aba47SJacob Keller 	rcu_read_unlock();
296109aba47SJacob Keller 
297109aba47SJacob Keller 	return is_vf_promisc;
298109aba47SJacob Keller }
299109aba47SJacob Keller 
300109aba47SJacob Keller /**
301109aba47SJacob Keller  * ice_vf_set_vsi_promisc - Enable promiscuous mode for a VF VSI
302109aba47SJacob Keller  * @vf: the VF to configure
303109aba47SJacob Keller  * @vsi: the VF's VSI
304109aba47SJacob Keller  * @promisc_m: the promiscuous mode to enable
305109aba47SJacob Keller  */
306109aba47SJacob Keller int
307109aba47SJacob Keller ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
308109aba47SJacob Keller {
309109aba47SJacob Keller 	struct ice_hw *hw = &vsi->back->hw;
310109aba47SJacob Keller 	int status;
311109aba47SJacob Keller 
312109aba47SJacob Keller 	if (ice_vf_is_port_vlan_ena(vf))
313109aba47SJacob Keller 		status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m,
314109aba47SJacob Keller 						  ice_vf_get_port_vlan_id(vf));
315109aba47SJacob Keller 	else if (ice_vsi_has_non_zero_vlans(vsi))
316109aba47SJacob Keller 		status = ice_fltr_set_vlan_vsi_promisc(hw, vsi, promisc_m);
317109aba47SJacob Keller 	else
318109aba47SJacob Keller 		status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m, 0);
319109aba47SJacob Keller 
320109aba47SJacob Keller 	if (status && status != -EEXIST) {
321109aba47SJacob Keller 		dev_err(ice_pf_to_dev(vsi->back), "enable Tx/Rx filter promiscuous mode on VF-%u failed, error: %d\n",
322109aba47SJacob Keller 			vf->vf_id, status);
323109aba47SJacob Keller 		return status;
324109aba47SJacob Keller 	}
325109aba47SJacob Keller 
326109aba47SJacob Keller 	return 0;
327109aba47SJacob Keller }
328109aba47SJacob Keller 
329109aba47SJacob Keller /**
330109aba47SJacob Keller  * ice_vf_clear_vsi_promisc - Disable promiscuous mode for a VF VSI
331109aba47SJacob Keller  * @vf: the VF to configure
332109aba47SJacob Keller  * @vsi: the VF's VSI
333109aba47SJacob Keller  * @promisc_m: the promiscuous mode to disable
334109aba47SJacob Keller  */
335109aba47SJacob Keller int
336109aba47SJacob Keller ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
337109aba47SJacob Keller {
338109aba47SJacob Keller 	struct ice_hw *hw = &vsi->back->hw;
339109aba47SJacob Keller 	int status;
340109aba47SJacob Keller 
341109aba47SJacob Keller 	if (ice_vf_is_port_vlan_ena(vf))
342109aba47SJacob Keller 		status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m,
343109aba47SJacob Keller 						    ice_vf_get_port_vlan_id(vf));
344109aba47SJacob Keller 	else if (ice_vsi_has_non_zero_vlans(vsi))
345109aba47SJacob Keller 		status = ice_fltr_clear_vlan_vsi_promisc(hw, vsi, promisc_m);
346109aba47SJacob Keller 	else
347109aba47SJacob Keller 		status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m, 0);
348109aba47SJacob Keller 
349109aba47SJacob Keller 	if (status && status != -ENOENT) {
350109aba47SJacob Keller 		dev_err(ice_pf_to_dev(vsi->back), "disable Tx/Rx filter promiscuous mode on VF-%u failed, error: %d\n",
351109aba47SJacob Keller 			vf->vf_id, status);
352109aba47SJacob Keller 		return status;
353109aba47SJacob Keller 	}
354109aba47SJacob Keller 
355109aba47SJacob Keller 	return 0;
356109aba47SJacob Keller }
357109aba47SJacob Keller 
358109aba47SJacob Keller /**
35916686d7fSJacob Keller  * ice_reset_all_vfs - reset all allocated VFs in one go
36016686d7fSJacob Keller  * @pf: pointer to the PF structure
36116686d7fSJacob Keller  *
36200be8197SJacob Keller  * Reset all VFs at once, in response to a PF or other device reset.
36300be8197SJacob Keller  *
36416686d7fSJacob Keller  * First, tell the hardware to reset each VF, then do all the waiting in one
36516686d7fSJacob Keller  * chunk, and finally finish restoring each VF after the wait. This is useful
36616686d7fSJacob Keller  * during PF routines which need to reset all VFs, as otherwise it must perform
36716686d7fSJacob Keller  * these resets in a serialized fashion.
36816686d7fSJacob Keller  */
369fe99d1c0SJacob Keller void ice_reset_all_vfs(struct ice_pf *pf)
37016686d7fSJacob Keller {
37116686d7fSJacob Keller 	struct device *dev = ice_pf_to_dev(pf);
37216686d7fSJacob Keller 	struct ice_hw *hw = &pf->hw;
37316686d7fSJacob Keller 	struct ice_vf *vf;
37416686d7fSJacob Keller 	unsigned int bkt;
37516686d7fSJacob Keller 
37616686d7fSJacob Keller 	/* If we don't have any VFs, then there is nothing to reset */
37716686d7fSJacob Keller 	if (!ice_has_vfs(pf))
378fe99d1c0SJacob Keller 		return;
37916686d7fSJacob Keller 
38016686d7fSJacob Keller 	mutex_lock(&pf->vfs.table_lock);
38116686d7fSJacob Keller 
38216686d7fSJacob Keller 	/* clear all malicious info if the VFs are getting reset */
38316686d7fSJacob Keller 	ice_for_each_vf(pf, bkt, vf)
38416686d7fSJacob Keller 		if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs,
38516686d7fSJacob Keller 					ICE_MAX_SRIOV_VFS, vf->vf_id))
38616686d7fSJacob Keller 			dev_dbg(dev, "failed to clear malicious VF state for VF %u\n",
38716686d7fSJacob Keller 				vf->vf_id);
38816686d7fSJacob Keller 
38916686d7fSJacob Keller 	/* If VFs have been disabled, there is no need to reset */
39016686d7fSJacob Keller 	if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
39116686d7fSJacob Keller 		mutex_unlock(&pf->vfs.table_lock);
392fe99d1c0SJacob Keller 		return;
39316686d7fSJacob Keller 	}
39416686d7fSJacob Keller 
39516686d7fSJacob Keller 	/* Begin reset on all VFs at once */
39616686d7fSJacob Keller 	ice_for_each_vf(pf, bkt, vf)
397dac57288SJacob Keller 		ice_trigger_vf_reset(vf, true, true);
39816686d7fSJacob Keller 
39916686d7fSJacob Keller 	/* HW requires some time to make sure it can flush the FIFO for a VF
40016686d7fSJacob Keller 	 * when it resets it. Now that we've triggered all of the VFs, iterate
40116686d7fSJacob Keller 	 * the table again and wait for each VF to complete.
40216686d7fSJacob Keller 	 */
40316686d7fSJacob Keller 	ice_for_each_vf(pf, bkt, vf) {
40416686d7fSJacob Keller 		if (!vf->vf_ops->poll_reset_status(vf)) {
40516686d7fSJacob Keller 			/* Display a warning if at least one VF didn't manage
40616686d7fSJacob Keller 			 * to reset in time, but continue on with the
40716686d7fSJacob Keller 			 * operation.
40816686d7fSJacob Keller 			 */
40916686d7fSJacob Keller 			dev_warn(dev, "VF %u reset check timeout\n", vf->vf_id);
41016686d7fSJacob Keller 			break;
41116686d7fSJacob Keller 		}
41216686d7fSJacob Keller 	}
41316686d7fSJacob Keller 
41416686d7fSJacob Keller 	/* free VF resources to begin resetting the VSI state */
41516686d7fSJacob Keller 	ice_for_each_vf(pf, bkt, vf) {
41616686d7fSJacob Keller 		mutex_lock(&vf->cfg_lock);
41716686d7fSJacob Keller 
41816686d7fSJacob Keller 		vf->driver_caps = 0;
41916686d7fSJacob Keller 		ice_vc_set_default_allowlist(vf);
42016686d7fSJacob Keller 
42116686d7fSJacob Keller 		ice_vf_fdir_exit(vf);
42216686d7fSJacob Keller 		ice_vf_fdir_init(vf);
42316686d7fSJacob Keller 		/* clean VF control VSI when resetting VFs since it should be
42416686d7fSJacob Keller 		 * setup only when VF creates its first FDIR rule.
42516686d7fSJacob Keller 		 */
42616686d7fSJacob Keller 		if (vf->ctrl_vsi_idx != ICE_NO_VSI)
42716686d7fSJacob Keller 			ice_vf_ctrl_invalidate_vsi(vf);
42816686d7fSJacob Keller 
42916686d7fSJacob Keller 		ice_vf_pre_vsi_rebuild(vf);
43016686d7fSJacob Keller 		ice_vf_rebuild_vsi(vf);
43116686d7fSJacob Keller 		vf->vf_ops->post_vsi_rebuild(vf);
43216686d7fSJacob Keller 
43316686d7fSJacob Keller 		mutex_unlock(&vf->cfg_lock);
43416686d7fSJacob Keller 	}
43516686d7fSJacob Keller 
43616686d7fSJacob Keller 	if (ice_is_eswitch_mode_switchdev(pf))
43716686d7fSJacob Keller 		if (ice_eswitch_rebuild(pf))
43816686d7fSJacob Keller 			dev_warn(dev, "eswitch rebuild failed\n");
43916686d7fSJacob Keller 
44016686d7fSJacob Keller 	ice_flush(hw);
44116686d7fSJacob Keller 	clear_bit(ICE_VF_DIS, pf->state);
44216686d7fSJacob Keller 
44316686d7fSJacob Keller 	mutex_unlock(&pf->vfs.table_lock);
44416686d7fSJacob Keller }
44516686d7fSJacob Keller 
44616686d7fSJacob Keller /**
4479dbb33daSJacob Keller  * ice_notify_vf_reset - Notify VF of a reset event
4489dbb33daSJacob Keller  * @vf: pointer to the VF structure
4499dbb33daSJacob Keller  */
4509dbb33daSJacob Keller static void ice_notify_vf_reset(struct ice_vf *vf)
4519dbb33daSJacob Keller {
4529dbb33daSJacob Keller 	struct ice_hw *hw = &vf->pf->hw;
4539dbb33daSJacob Keller 	struct virtchnl_pf_event pfe;
4549dbb33daSJacob Keller 
4559dbb33daSJacob Keller 	/* Bail out if VF is in disabled state, neither initialized, nor active
4569dbb33daSJacob Keller 	 * state - otherwise proceed with notifications
4579dbb33daSJacob Keller 	 */
4589dbb33daSJacob Keller 	if ((!test_bit(ICE_VF_STATE_INIT, vf->vf_states) &&
4599dbb33daSJacob Keller 	     !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) ||
4609dbb33daSJacob Keller 	    test_bit(ICE_VF_STATE_DIS, vf->vf_states))
4619dbb33daSJacob Keller 		return;
4629dbb33daSJacob Keller 
4639dbb33daSJacob Keller 	pfe.event = VIRTCHNL_EVENT_RESET_IMPENDING;
4649dbb33daSJacob Keller 	pfe.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM;
4659dbb33daSJacob Keller 	ice_aq_send_msg_to_vf(hw, vf->vf_id, VIRTCHNL_OP_EVENT,
4669dbb33daSJacob Keller 			      VIRTCHNL_STATUS_SUCCESS, (u8 *)&pfe, sizeof(pfe),
4679dbb33daSJacob Keller 			      NULL);
4689dbb33daSJacob Keller }
4699dbb33daSJacob Keller 
4709dbb33daSJacob Keller /**
47116686d7fSJacob Keller  * ice_reset_vf - Reset a particular VF
47216686d7fSJacob Keller  * @vf: pointer to the VF structure
4737eb517e4SJacob Keller  * @flags: flags controlling behavior of the reset
4747eb517e4SJacob Keller  *
4757eb517e4SJacob Keller  * Flags:
4767eb517e4SJacob Keller  *   ICE_VF_RESET_VFLR - Indicates a reset is due to VFLR event
4779dbb33daSJacob Keller  *   ICE_VF_RESET_NOTIFY - Send VF a notification prior to reset
478f5f085c0SJacob Keller  *   ICE_VF_RESET_LOCK - Acquire VF cfg_lock before resetting
47916686d7fSJacob Keller  *
48019c3e1edSJacob Keller  * Returns 0 if the VF is currently in reset, if resets are disabled, or if
48119c3e1edSJacob Keller  * the VF resets successfully. Returns an error code if the VF fails to
4824fe193ccSJacob Keller  * rebuild.
48316686d7fSJacob Keller  */
4847eb517e4SJacob Keller int ice_reset_vf(struct ice_vf *vf, u32 flags)
48516686d7fSJacob Keller {
48616686d7fSJacob Keller 	struct ice_pf *pf = vf->pf;
48716686d7fSJacob Keller 	struct ice_vsi *vsi;
48816686d7fSJacob Keller 	struct device *dev;
48916686d7fSJacob Keller 	struct ice_hw *hw;
49016686d7fSJacob Keller 	u8 promisc_m;
491f5f085c0SJacob Keller 	int err = 0;
49216686d7fSJacob Keller 	bool rsd;
49316686d7fSJacob Keller 
49416686d7fSJacob Keller 	dev = ice_pf_to_dev(pf);
49516686d7fSJacob Keller 	hw = &pf->hw;
49616686d7fSJacob Keller 
4979dbb33daSJacob Keller 	if (flags & ICE_VF_RESET_NOTIFY)
4989dbb33daSJacob Keller 		ice_notify_vf_reset(vf);
4999dbb33daSJacob Keller 
50016686d7fSJacob Keller 	if (test_bit(ICE_VF_RESETS_DISABLED, pf->state)) {
50116686d7fSJacob Keller 		dev_dbg(dev, "Trying to reset VF %d, but all VF resets are disabled\n",
50216686d7fSJacob Keller 			vf->vf_id);
5034fe193ccSJacob Keller 		return 0;
50416686d7fSJacob Keller 	}
50516686d7fSJacob Keller 
50616686d7fSJacob Keller 	if (ice_is_vf_disabled(vf)) {
507efe41860SPrzemyslaw Patynowski 		vsi = ice_get_vf_vsi(vf);
508efe41860SPrzemyslaw Patynowski 		if (WARN_ON(!vsi))
509efe41860SPrzemyslaw Patynowski 			return -EINVAL;
510efe41860SPrzemyslaw Patynowski 		ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
511efe41860SPrzemyslaw Patynowski 		ice_vsi_stop_all_rx_rings(vsi);
51216686d7fSJacob Keller 		dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
51316686d7fSJacob Keller 			vf->vf_id);
5144fe193ccSJacob Keller 		return 0;
51516686d7fSJacob Keller 	}
51616686d7fSJacob Keller 
517f5f085c0SJacob Keller 	if (flags & ICE_VF_RESET_LOCK)
518f5f085c0SJacob Keller 		mutex_lock(&vf->cfg_lock);
519f5f085c0SJacob Keller 	else
520f5f085c0SJacob Keller 		lockdep_assert_held(&vf->cfg_lock);
521f5f085c0SJacob Keller 
52216686d7fSJacob Keller 	/* Set VF disable bit state here, before triggering reset */
52316686d7fSJacob Keller 	set_bit(ICE_VF_STATE_DIS, vf->vf_states);
5247eb517e4SJacob Keller 	ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false);
52516686d7fSJacob Keller 
52616686d7fSJacob Keller 	vsi = ice_get_vf_vsi(vf);
527baeb705fSJacob Keller 	if (WARN_ON(!vsi)) {
528baeb705fSJacob Keller 		err = -EIO;
529baeb705fSJacob Keller 		goto out_unlock;
530baeb705fSJacob Keller 	}
53116686d7fSJacob Keller 
53216686d7fSJacob Keller 	ice_dis_vf_qs(vf);
53316686d7fSJacob Keller 
53416686d7fSJacob Keller 	/* Call Disable LAN Tx queue AQ whether or not queues are
53516686d7fSJacob Keller 	 * enabled. This is needed for successful completion of VFR.
53616686d7fSJacob Keller 	 */
53716686d7fSJacob Keller 	ice_dis_vsi_txq(vsi->port_info, vsi->idx, 0, 0, NULL, NULL,
53816686d7fSJacob Keller 			NULL, vf->vf_ops->reset_type, vf->vf_id, NULL);
53916686d7fSJacob Keller 
54016686d7fSJacob Keller 	/* poll VPGEN_VFRSTAT reg to make sure
54116686d7fSJacob Keller 	 * that reset is complete
54216686d7fSJacob Keller 	 */
54316686d7fSJacob Keller 	rsd = vf->vf_ops->poll_reset_status(vf);
54416686d7fSJacob Keller 
54516686d7fSJacob Keller 	/* Display a warning if VF didn't manage to reset in time, but need to
54616686d7fSJacob Keller 	 * continue on with the operation.
54716686d7fSJacob Keller 	 */
54816686d7fSJacob Keller 	if (!rsd)
54916686d7fSJacob Keller 		dev_warn(dev, "VF reset check timeout on VF %d\n", vf->vf_id);
55016686d7fSJacob Keller 
55116686d7fSJacob Keller 	vf->driver_caps = 0;
55216686d7fSJacob Keller 	ice_vc_set_default_allowlist(vf);
55316686d7fSJacob Keller 
55416686d7fSJacob Keller 	/* disable promiscuous modes in case they were enabled
55516686d7fSJacob Keller 	 * ignore any error if disabling process failed
55616686d7fSJacob Keller 	 */
55716686d7fSJacob Keller 	if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) ||
55816686d7fSJacob Keller 	    test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) {
55916686d7fSJacob Keller 		if (ice_vf_is_port_vlan_ena(vf) || vsi->num_vlan)
56016686d7fSJacob Keller 			promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
56116686d7fSJacob Keller 		else
56216686d7fSJacob Keller 			promisc_m = ICE_UCAST_PROMISC_BITS;
56316686d7fSJacob Keller 
56416686d7fSJacob Keller 		if (ice_vf_clear_vsi_promisc(vf, vsi, promisc_m))
56516686d7fSJacob Keller 			dev_err(dev, "disabling promiscuous mode failed\n");
56616686d7fSJacob Keller 	}
56716686d7fSJacob Keller 
56816686d7fSJacob Keller 	ice_eswitch_del_vf_mac_rule(vf);
56916686d7fSJacob Keller 
57016686d7fSJacob Keller 	ice_vf_fdir_exit(vf);
57116686d7fSJacob Keller 	ice_vf_fdir_init(vf);
57216686d7fSJacob Keller 	/* clean VF control VSI when resetting VF since it should be setup
57316686d7fSJacob Keller 	 * only when VF creates its first FDIR rule.
57416686d7fSJacob Keller 	 */
57516686d7fSJacob Keller 	if (vf->ctrl_vsi_idx != ICE_NO_VSI)
57616686d7fSJacob Keller 		ice_vf_ctrl_vsi_release(vf);
57716686d7fSJacob Keller 
57816686d7fSJacob Keller 	ice_vf_pre_vsi_rebuild(vf);
57916686d7fSJacob Keller 
58016686d7fSJacob Keller 	if (vf->vf_ops->vsi_rebuild(vf)) {
58116686d7fSJacob Keller 		dev_err(dev, "Failed to release and setup the VF%u's VSI\n",
58216686d7fSJacob Keller 			vf->vf_id);
583f5f085c0SJacob Keller 		err = -EFAULT;
584f5f085c0SJacob Keller 		goto out_unlock;
58516686d7fSJacob Keller 	}
58616686d7fSJacob Keller 
58716686d7fSJacob Keller 	vf->vf_ops->post_vsi_rebuild(vf);
58816686d7fSJacob Keller 	vsi = ice_get_vf_vsi(vf);
589baeb705fSJacob Keller 	if (WARN_ON(!vsi)) {
590baeb705fSJacob Keller 		err = -EINVAL;
591baeb705fSJacob Keller 		goto out_unlock;
592baeb705fSJacob Keller 	}
593baeb705fSJacob Keller 
59416686d7fSJacob Keller 	ice_eswitch_update_repr(vsi);
59516686d7fSJacob Keller 	ice_eswitch_replay_vf_mac_rule(vf);
59616686d7fSJacob Keller 
59716686d7fSJacob Keller 	/* if the VF has been reset allow it to come up again */
59816686d7fSJacob Keller 	if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs,
59916686d7fSJacob Keller 				ICE_MAX_SRIOV_VFS, vf->vf_id))
60016686d7fSJacob Keller 		dev_dbg(dev, "failed to clear malicious VF state for VF %u\n",
60116686d7fSJacob Keller 			vf->vf_id);
60216686d7fSJacob Keller 
603f5f085c0SJacob Keller out_unlock:
604f5f085c0SJacob Keller 	if (flags & ICE_VF_RESET_LOCK)
605f5f085c0SJacob Keller 		mutex_unlock(&vf->cfg_lock);
606f5f085c0SJacob Keller 
607f5f085c0SJacob Keller 	return err;
60816686d7fSJacob Keller }
60916686d7fSJacob Keller 
61016686d7fSJacob Keller /**
611109aba47SJacob Keller  * ice_set_vf_state_qs_dis - Set VF queues state to disabled
612109aba47SJacob Keller  * @vf: pointer to the VF structure
613109aba47SJacob Keller  */
614109aba47SJacob Keller void ice_set_vf_state_qs_dis(struct ice_vf *vf)
615109aba47SJacob Keller {
616109aba47SJacob Keller 	/* Clear Rx/Tx enabled queues flag */
617109aba47SJacob Keller 	bitmap_zero(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF);
618109aba47SJacob Keller 	bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF);
619109aba47SJacob Keller 	clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
620109aba47SJacob Keller }
621109aba47SJacob Keller 
622109aba47SJacob Keller /* Private functions only accessed from other virtualization files */
623109aba47SJacob Keller 
624109aba47SJacob Keller /**
625109aba47SJacob Keller  * ice_dis_vf_qs - Disable the VF queues
626109aba47SJacob Keller  * @vf: pointer to the VF structure
627109aba47SJacob Keller  */
628109aba47SJacob Keller void ice_dis_vf_qs(struct ice_vf *vf)
629109aba47SJacob Keller {
630109aba47SJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
631109aba47SJacob Keller 
632baeb705fSJacob Keller 	if (WARN_ON(!vsi))
633baeb705fSJacob Keller 		return;
634baeb705fSJacob Keller 
635109aba47SJacob Keller 	ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
636109aba47SJacob Keller 	ice_vsi_stop_all_rx_rings(vsi);
637109aba47SJacob Keller 	ice_set_vf_state_qs_dis(vf);
638109aba47SJacob Keller }
639109aba47SJacob Keller 
640109aba47SJacob Keller /**
641109aba47SJacob Keller  * ice_check_vf_init - helper to check if VF init complete
642109aba47SJacob Keller  * @vf: the pointer to the VF to check
643109aba47SJacob Keller  */
6445a57ee83SJacob Keller int ice_check_vf_init(struct ice_vf *vf)
645109aba47SJacob Keller {
6465a57ee83SJacob Keller 	struct ice_pf *pf = vf->pf;
6475a57ee83SJacob Keller 
648109aba47SJacob Keller 	if (!test_bit(ICE_VF_STATE_INIT, vf->vf_states)) {
649109aba47SJacob Keller 		dev_err(ice_pf_to_dev(pf), "VF ID: %u in reset. Try again.\n",
650109aba47SJacob Keller 			vf->vf_id);
651109aba47SJacob Keller 		return -EBUSY;
652109aba47SJacob Keller 	}
653109aba47SJacob Keller 	return 0;
654109aba47SJacob Keller }
655109aba47SJacob Keller 
656109aba47SJacob Keller /**
657109aba47SJacob Keller  * ice_vf_get_port_info - Get the VF's port info structure
658109aba47SJacob Keller  * @vf: VF used to get the port info structure for
659109aba47SJacob Keller  */
660109aba47SJacob Keller struct ice_port_info *ice_vf_get_port_info(struct ice_vf *vf)
661109aba47SJacob Keller {
662109aba47SJacob Keller 	return vf->pf->hw.port_info;
663109aba47SJacob Keller }
664109aba47SJacob Keller 
66571c114e8SJacob Keller /**
66671c114e8SJacob Keller  * ice_cfg_mac_antispoof - Configure MAC antispoof checking behavior
66771c114e8SJacob Keller  * @vsi: the VSI to configure
66871c114e8SJacob Keller  * @enable: whether to enable or disable the spoof checking
66971c114e8SJacob Keller  *
67071c114e8SJacob Keller  * Configure a VSI to enable (or disable) spoof checking behavior.
67171c114e8SJacob Keller  */
672109aba47SJacob Keller static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable)
673109aba47SJacob Keller {
674109aba47SJacob Keller 	struct ice_vsi_ctx *ctx;
675109aba47SJacob Keller 	int err;
676109aba47SJacob Keller 
677109aba47SJacob Keller 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
678109aba47SJacob Keller 	if (!ctx)
679109aba47SJacob Keller 		return -ENOMEM;
680109aba47SJacob Keller 
681109aba47SJacob Keller 	ctx->info.sec_flags = vsi->info.sec_flags;
682109aba47SJacob Keller 	ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID);
683109aba47SJacob Keller 
684109aba47SJacob Keller 	if (enable)
685109aba47SJacob Keller 		ctx->info.sec_flags |= ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF;
686109aba47SJacob Keller 	else
687109aba47SJacob Keller 		ctx->info.sec_flags &= ~ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF;
688109aba47SJacob Keller 
689109aba47SJacob Keller 	err = ice_update_vsi(&vsi->back->hw, vsi->idx, ctx, NULL);
690109aba47SJacob Keller 	if (err)
691109aba47SJacob Keller 		dev_err(ice_pf_to_dev(vsi->back), "Failed to configure Tx MAC anti-spoof %s for VSI %d, error %d\n",
692109aba47SJacob Keller 			enable ? "ON" : "OFF", vsi->vsi_num, err);
693109aba47SJacob Keller 	else
694109aba47SJacob Keller 		vsi->info.sec_flags = ctx->info.sec_flags;
695109aba47SJacob Keller 
696109aba47SJacob Keller 	kfree(ctx);
697109aba47SJacob Keller 
698109aba47SJacob Keller 	return err;
699109aba47SJacob Keller }
700109aba47SJacob Keller 
701109aba47SJacob Keller /**
702109aba47SJacob Keller  * ice_vsi_ena_spoofchk - enable Tx spoof checking for this VSI
703109aba47SJacob Keller  * @vsi: VSI to enable Tx spoof checking for
704109aba47SJacob Keller  */
705109aba47SJacob Keller static int ice_vsi_ena_spoofchk(struct ice_vsi *vsi)
706109aba47SJacob Keller {
707109aba47SJacob Keller 	struct ice_vsi_vlan_ops *vlan_ops;
708109aba47SJacob Keller 	int err;
709109aba47SJacob Keller 
710109aba47SJacob Keller 	vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
711109aba47SJacob Keller 
712109aba47SJacob Keller 	err = vlan_ops->ena_tx_filtering(vsi);
713109aba47SJacob Keller 	if (err)
714109aba47SJacob Keller 		return err;
715109aba47SJacob Keller 
716109aba47SJacob Keller 	return ice_cfg_mac_antispoof(vsi, true);
717109aba47SJacob Keller }
718109aba47SJacob Keller 
719109aba47SJacob Keller /**
720109aba47SJacob Keller  * ice_vsi_dis_spoofchk - disable Tx spoof checking for this VSI
721109aba47SJacob Keller  * @vsi: VSI to disable Tx spoof checking for
722109aba47SJacob Keller  */
723109aba47SJacob Keller static int ice_vsi_dis_spoofchk(struct ice_vsi *vsi)
724109aba47SJacob Keller {
725109aba47SJacob Keller 	struct ice_vsi_vlan_ops *vlan_ops;
726109aba47SJacob Keller 	int err;
727109aba47SJacob Keller 
728109aba47SJacob Keller 	vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
729109aba47SJacob Keller 
730109aba47SJacob Keller 	err = vlan_ops->dis_tx_filtering(vsi);
731109aba47SJacob Keller 	if (err)
732109aba47SJacob Keller 		return err;
733109aba47SJacob Keller 
734109aba47SJacob Keller 	return ice_cfg_mac_antispoof(vsi, false);
735109aba47SJacob Keller }
736109aba47SJacob Keller 
737109aba47SJacob Keller /**
738109aba47SJacob Keller  * ice_vsi_apply_spoofchk - Apply Tx spoof checking setting to a VSI
739109aba47SJacob Keller  * @vsi: VSI associated to the VF
740109aba47SJacob Keller  * @enable: whether to enable or disable the spoof checking
741109aba47SJacob Keller  */
742109aba47SJacob Keller int ice_vsi_apply_spoofchk(struct ice_vsi *vsi, bool enable)
743109aba47SJacob Keller {
744109aba47SJacob Keller 	int err;
745109aba47SJacob Keller 
746109aba47SJacob Keller 	if (enable)
747109aba47SJacob Keller 		err = ice_vsi_ena_spoofchk(vsi);
748109aba47SJacob Keller 	else
749109aba47SJacob Keller 		err = ice_vsi_dis_spoofchk(vsi);
750109aba47SJacob Keller 
751109aba47SJacob Keller 	return err;
752109aba47SJacob Keller }
753109aba47SJacob Keller 
754109aba47SJacob Keller /**
755109aba47SJacob Keller  * ice_is_vf_trusted
756109aba47SJacob Keller  * @vf: pointer to the VF info
757109aba47SJacob Keller  */
758109aba47SJacob Keller bool ice_is_vf_trusted(struct ice_vf *vf)
759109aba47SJacob Keller {
760109aba47SJacob Keller 	return test_bit(ICE_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
761109aba47SJacob Keller }
762109aba47SJacob Keller 
763109aba47SJacob Keller /**
764109aba47SJacob Keller  * ice_vf_has_no_qs_ena - check if the VF has any Rx or Tx queues enabled
765109aba47SJacob Keller  * @vf: the VF to check
766109aba47SJacob Keller  *
767109aba47SJacob Keller  * Returns true if the VF has no Rx and no Tx queues enabled and returns false
768109aba47SJacob Keller  * otherwise
769109aba47SJacob Keller  */
770109aba47SJacob Keller bool ice_vf_has_no_qs_ena(struct ice_vf *vf)
771109aba47SJacob Keller {
772109aba47SJacob Keller 	return (!bitmap_weight(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF) &&
773109aba47SJacob Keller 		!bitmap_weight(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF));
774109aba47SJacob Keller }
775109aba47SJacob Keller 
776109aba47SJacob Keller /**
777109aba47SJacob Keller  * ice_is_vf_link_up - check if the VF's link is up
778109aba47SJacob Keller  * @vf: VF to check if link is up
779109aba47SJacob Keller  */
780109aba47SJacob Keller bool ice_is_vf_link_up(struct ice_vf *vf)
781109aba47SJacob Keller {
7825a57ee83SJacob Keller 	struct ice_port_info *pi = ice_vf_get_port_info(vf);
783109aba47SJacob Keller 
7845a57ee83SJacob Keller 	if (ice_check_vf_init(vf))
785109aba47SJacob Keller 		return false;
786109aba47SJacob Keller 
787109aba47SJacob Keller 	if (ice_vf_has_no_qs_ena(vf))
788109aba47SJacob Keller 		return false;
789109aba47SJacob Keller 	else if (vf->link_forced)
790109aba47SJacob Keller 		return vf->link_up;
791109aba47SJacob Keller 	else
7925a57ee83SJacob Keller 		return pi->phy.link_info.link_info &
793109aba47SJacob Keller 			ICE_AQ_LINK_UP;
794109aba47SJacob Keller }
795109aba47SJacob Keller 
796109aba47SJacob Keller /**
79716686d7fSJacob Keller  * ice_vf_set_host_trust_cfg - set trust setting based on pre-reset value
79816686d7fSJacob Keller  * @vf: VF to configure trust setting for
79916686d7fSJacob Keller  */
80016686d7fSJacob Keller static void ice_vf_set_host_trust_cfg(struct ice_vf *vf)
80116686d7fSJacob Keller {
80216686d7fSJacob Keller 	if (vf->trusted)
80316686d7fSJacob Keller 		set_bit(ICE_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
80416686d7fSJacob Keller 	else
80516686d7fSJacob Keller 		clear_bit(ICE_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
80616686d7fSJacob Keller }
80716686d7fSJacob Keller 
80816686d7fSJacob Keller /**
80916686d7fSJacob Keller  * ice_vf_rebuild_host_mac_cfg - add broadcast and the VF's perm_addr/LAA
81016686d7fSJacob Keller  * @vf: VF to add MAC filters for
81116686d7fSJacob Keller  *
81216686d7fSJacob Keller  * Called after a VF VSI has been re-added/rebuilt during reset. The PF driver
81316686d7fSJacob Keller  * always re-adds a broadcast filter and the VF's perm_addr/LAA after reset.
81416686d7fSJacob Keller  */
81516686d7fSJacob Keller static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
81616686d7fSJacob Keller {
81716686d7fSJacob Keller 	struct device *dev = ice_pf_to_dev(vf->pf);
81816686d7fSJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
81916686d7fSJacob Keller 	u8 broadcast[ETH_ALEN];
82016686d7fSJacob Keller 	int status;
82116686d7fSJacob Keller 
822baeb705fSJacob Keller 	if (WARN_ON(!vsi))
823baeb705fSJacob Keller 		return -EINVAL;
824baeb705fSJacob Keller 
82516686d7fSJacob Keller 	if (ice_is_eswitch_mode_switchdev(vf->pf))
82616686d7fSJacob Keller 		return 0;
82716686d7fSJacob Keller 
82816686d7fSJacob Keller 	eth_broadcast_addr(broadcast);
82916686d7fSJacob Keller 	status = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
83016686d7fSJacob Keller 	if (status) {
83116686d7fSJacob Keller 		dev_err(dev, "failed to add broadcast MAC filter for VF %u, error %d\n",
83216686d7fSJacob Keller 			vf->vf_id, status);
83316686d7fSJacob Keller 		return status;
83416686d7fSJacob Keller 	}
83516686d7fSJacob Keller 
83616686d7fSJacob Keller 	vf->num_mac++;
83716686d7fSJacob Keller 
83816686d7fSJacob Keller 	if (is_valid_ether_addr(vf->hw_lan_addr.addr)) {
83916686d7fSJacob Keller 		status = ice_fltr_add_mac(vsi, vf->hw_lan_addr.addr,
84016686d7fSJacob Keller 					  ICE_FWD_TO_VSI);
84116686d7fSJacob Keller 		if (status) {
84216686d7fSJacob Keller 			dev_err(dev, "failed to add default unicast MAC filter %pM for VF %u, error %d\n",
84316686d7fSJacob Keller 				&vf->hw_lan_addr.addr[0], vf->vf_id,
84416686d7fSJacob Keller 				status);
84516686d7fSJacob Keller 			return status;
84616686d7fSJacob Keller 		}
84716686d7fSJacob Keller 		vf->num_mac++;
84816686d7fSJacob Keller 
84916686d7fSJacob Keller 		ether_addr_copy(vf->dev_lan_addr.addr, vf->hw_lan_addr.addr);
85016686d7fSJacob Keller 	}
85116686d7fSJacob Keller 
85216686d7fSJacob Keller 	return 0;
85316686d7fSJacob Keller }
85416686d7fSJacob Keller 
85516686d7fSJacob Keller /**
85616686d7fSJacob Keller  * ice_vf_rebuild_host_vlan_cfg - add VLAN 0 filter or rebuild the Port VLAN
85716686d7fSJacob Keller  * @vf: VF to add MAC filters for
85816686d7fSJacob Keller  * @vsi: Pointer to VSI
85916686d7fSJacob Keller  *
86016686d7fSJacob Keller  * Called after a VF VSI has been re-added/rebuilt during reset. The PF driver
86116686d7fSJacob Keller  * always re-adds either a VLAN 0 or port VLAN based filter after reset.
86216686d7fSJacob Keller  */
86316686d7fSJacob Keller static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
86416686d7fSJacob Keller {
86516686d7fSJacob Keller 	struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
86616686d7fSJacob Keller 	struct device *dev = ice_pf_to_dev(vf->pf);
86716686d7fSJacob Keller 	int err;
86816686d7fSJacob Keller 
86916686d7fSJacob Keller 	if (ice_vf_is_port_vlan_ena(vf)) {
87016686d7fSJacob Keller 		err = vlan_ops->set_port_vlan(vsi, &vf->port_vlan_info);
87116686d7fSJacob Keller 		if (err) {
87216686d7fSJacob Keller 			dev_err(dev, "failed to configure port VLAN via VSI parameters for VF %u, error %d\n",
87316686d7fSJacob Keller 				vf->vf_id, err);
87416686d7fSJacob Keller 			return err;
87516686d7fSJacob Keller 		}
87616686d7fSJacob Keller 
87716686d7fSJacob Keller 		err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info);
87816686d7fSJacob Keller 	} else {
87916686d7fSJacob Keller 		err = ice_vsi_add_vlan_zero(vsi);
88016686d7fSJacob Keller 	}
88116686d7fSJacob Keller 
88216686d7fSJacob Keller 	if (err) {
88316686d7fSJacob Keller 		dev_err(dev, "failed to add VLAN %u filter for VF %u during VF rebuild, error %d\n",
88416686d7fSJacob Keller 			ice_vf_is_port_vlan_ena(vf) ?
88516686d7fSJacob Keller 			ice_vf_get_port_vlan_id(vf) : 0, vf->vf_id, err);
88616686d7fSJacob Keller 		return err;
88716686d7fSJacob Keller 	}
88816686d7fSJacob Keller 
88916686d7fSJacob Keller 	err = vlan_ops->ena_rx_filtering(vsi);
89016686d7fSJacob Keller 	if (err)
89116686d7fSJacob Keller 		dev_warn(dev, "failed to enable Rx VLAN filtering for VF %d VSI %d during VF rebuild, error %d\n",
89216686d7fSJacob Keller 			 vf->vf_id, vsi->idx, err);
89316686d7fSJacob Keller 
89416686d7fSJacob Keller 	return 0;
89516686d7fSJacob Keller }
89616686d7fSJacob Keller 
89716686d7fSJacob Keller /**
89816686d7fSJacob Keller  * ice_vf_rebuild_host_tx_rate_cfg - re-apply the Tx rate limiting configuration
89916686d7fSJacob Keller  * @vf: VF to re-apply the configuration for
90016686d7fSJacob Keller  *
90116686d7fSJacob Keller  * Called after a VF VSI has been re-added/rebuild during reset. The PF driver
90216686d7fSJacob Keller  * needs to re-apply the host configured Tx rate limiting configuration.
90316686d7fSJacob Keller  */
90416686d7fSJacob Keller static int ice_vf_rebuild_host_tx_rate_cfg(struct ice_vf *vf)
90516686d7fSJacob Keller {
90616686d7fSJacob Keller 	struct device *dev = ice_pf_to_dev(vf->pf);
90716686d7fSJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
90816686d7fSJacob Keller 	int err;
90916686d7fSJacob Keller 
910baeb705fSJacob Keller 	if (WARN_ON(!vsi))
911baeb705fSJacob Keller 		return -EINVAL;
912baeb705fSJacob Keller 
91316686d7fSJacob Keller 	if (vf->min_tx_rate) {
91416686d7fSJacob Keller 		err = ice_set_min_bw_limit(vsi, (u64)vf->min_tx_rate * 1000);
91516686d7fSJacob Keller 		if (err) {
91616686d7fSJacob Keller 			dev_err(dev, "failed to set min Tx rate to %d Mbps for VF %u, error %d\n",
91716686d7fSJacob Keller 				vf->min_tx_rate, vf->vf_id, err);
91816686d7fSJacob Keller 			return err;
91916686d7fSJacob Keller 		}
92016686d7fSJacob Keller 	}
92116686d7fSJacob Keller 
92216686d7fSJacob Keller 	if (vf->max_tx_rate) {
92316686d7fSJacob Keller 		err = ice_set_max_bw_limit(vsi, (u64)vf->max_tx_rate * 1000);
92416686d7fSJacob Keller 		if (err) {
92516686d7fSJacob Keller 			dev_err(dev, "failed to set max Tx rate to %d Mbps for VF %u, error %d\n",
92616686d7fSJacob Keller 				vf->max_tx_rate, vf->vf_id, err);
92716686d7fSJacob Keller 			return err;
92816686d7fSJacob Keller 		}
92916686d7fSJacob Keller 	}
93016686d7fSJacob Keller 
93116686d7fSJacob Keller 	return 0;
93216686d7fSJacob Keller }
93316686d7fSJacob Keller 
93416686d7fSJacob Keller /**
93516686d7fSJacob Keller  * ice_vf_rebuild_aggregator_node_cfg - rebuild aggregator node config
93616686d7fSJacob Keller  * @vsi: Pointer to VSI
93716686d7fSJacob Keller  *
93816686d7fSJacob Keller  * This function moves VSI into corresponding scheduler aggregator node
93916686d7fSJacob Keller  * based on cached value of "aggregator node info" per VSI
94016686d7fSJacob Keller  */
94116686d7fSJacob Keller static void ice_vf_rebuild_aggregator_node_cfg(struct ice_vsi *vsi)
94216686d7fSJacob Keller {
94316686d7fSJacob Keller 	struct ice_pf *pf = vsi->back;
94416686d7fSJacob Keller 	struct device *dev;
94516686d7fSJacob Keller 	int status;
94616686d7fSJacob Keller 
94716686d7fSJacob Keller 	if (!vsi->agg_node)
94816686d7fSJacob Keller 		return;
94916686d7fSJacob Keller 
95016686d7fSJacob Keller 	dev = ice_pf_to_dev(pf);
95116686d7fSJacob Keller 	if (vsi->agg_node->num_vsis == ICE_MAX_VSIS_IN_AGG_NODE) {
95216686d7fSJacob Keller 		dev_dbg(dev,
95316686d7fSJacob Keller 			"agg_id %u already has reached max_num_vsis %u\n",
95416686d7fSJacob Keller 			vsi->agg_node->agg_id, vsi->agg_node->num_vsis);
95516686d7fSJacob Keller 		return;
95616686d7fSJacob Keller 	}
95716686d7fSJacob Keller 
95816686d7fSJacob Keller 	status = ice_move_vsi_to_agg(pf->hw.port_info, vsi->agg_node->agg_id,
95916686d7fSJacob Keller 				     vsi->idx, vsi->tc_cfg.ena_tc);
96016686d7fSJacob Keller 	if (status)
96116686d7fSJacob Keller 		dev_dbg(dev, "unable to move VSI idx %u into aggregator %u node",
96216686d7fSJacob Keller 			vsi->idx, vsi->agg_node->agg_id);
96316686d7fSJacob Keller 	else
96416686d7fSJacob Keller 		vsi->agg_node->num_vsis++;
96516686d7fSJacob Keller }
96616686d7fSJacob Keller 
96716686d7fSJacob Keller /**
96816686d7fSJacob Keller  * ice_vf_rebuild_host_cfg - host admin configuration is persistent across reset
96916686d7fSJacob Keller  * @vf: VF to rebuild host configuration on
97016686d7fSJacob Keller  */
97116686d7fSJacob Keller void ice_vf_rebuild_host_cfg(struct ice_vf *vf)
97216686d7fSJacob Keller {
97316686d7fSJacob Keller 	struct device *dev = ice_pf_to_dev(vf->pf);
97416686d7fSJacob Keller 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
97516686d7fSJacob Keller 
976baeb705fSJacob Keller 	if (WARN_ON(!vsi))
977baeb705fSJacob Keller 		return;
978baeb705fSJacob Keller 
97916686d7fSJacob Keller 	ice_vf_set_host_trust_cfg(vf);
98016686d7fSJacob Keller 
98116686d7fSJacob Keller 	if (ice_vf_rebuild_host_mac_cfg(vf))
98216686d7fSJacob Keller 		dev_err(dev, "failed to rebuild default MAC configuration for VF %d\n",
98316686d7fSJacob Keller 			vf->vf_id);
98416686d7fSJacob Keller 
98516686d7fSJacob Keller 	if (ice_vf_rebuild_host_vlan_cfg(vf, vsi))
98616686d7fSJacob Keller 		dev_err(dev, "failed to rebuild VLAN configuration for VF %u\n",
98716686d7fSJacob Keller 			vf->vf_id);
98816686d7fSJacob Keller 
98916686d7fSJacob Keller 	if (ice_vf_rebuild_host_tx_rate_cfg(vf))
99016686d7fSJacob Keller 		dev_err(dev, "failed to rebuild Tx rate limiting configuration for VF %u\n",
99116686d7fSJacob Keller 			vf->vf_id);
99216686d7fSJacob Keller 
99316686d7fSJacob Keller 	if (ice_vsi_apply_spoofchk(vsi, vf->spoofchk))
99416686d7fSJacob Keller 		dev_err(dev, "failed to rebuild spoofchk configuration for VF %d\n",
99516686d7fSJacob Keller 			vf->vf_id);
99616686d7fSJacob Keller 
99716686d7fSJacob Keller 	/* rebuild aggregator node config for main VF VSI */
99816686d7fSJacob Keller 	ice_vf_rebuild_aggregator_node_cfg(vsi);
99916686d7fSJacob Keller }
100016686d7fSJacob Keller 
100116686d7fSJacob Keller /**
1002109aba47SJacob Keller  * ice_vf_ctrl_invalidate_vsi - invalidate ctrl_vsi_idx to remove VSI access
1003109aba47SJacob Keller  * @vf: VF that control VSI is being invalidated on
1004109aba47SJacob Keller  */
1005109aba47SJacob Keller void ice_vf_ctrl_invalidate_vsi(struct ice_vf *vf)
1006109aba47SJacob Keller {
1007109aba47SJacob Keller 	vf->ctrl_vsi_idx = ICE_NO_VSI;
1008109aba47SJacob Keller }
1009109aba47SJacob Keller 
1010109aba47SJacob Keller /**
1011109aba47SJacob Keller  * ice_vf_ctrl_vsi_release - invalidate the VF's control VSI after freeing it
1012109aba47SJacob Keller  * @vf: VF that control VSI is being released on
1013109aba47SJacob Keller  */
1014109aba47SJacob Keller void ice_vf_ctrl_vsi_release(struct ice_vf *vf)
1015109aba47SJacob Keller {
1016109aba47SJacob Keller 	ice_vsi_release(vf->pf->vsi[vf->ctrl_vsi_idx]);
1017109aba47SJacob Keller 	ice_vf_ctrl_invalidate_vsi(vf);
1018109aba47SJacob Keller }
1019109aba47SJacob Keller 
1020109aba47SJacob Keller /**
1021109aba47SJacob Keller  * ice_vf_ctrl_vsi_setup - Set up a VF control VSI
1022109aba47SJacob Keller  * @vf: VF to setup control VSI for
1023109aba47SJacob Keller  *
1024109aba47SJacob Keller  * Returns pointer to the successfully allocated VSI struct on success,
1025109aba47SJacob Keller  * otherwise returns NULL on failure.
1026109aba47SJacob Keller  */
1027109aba47SJacob Keller struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf)
1028109aba47SJacob Keller {
1029109aba47SJacob Keller 	struct ice_port_info *pi = ice_vf_get_port_info(vf);
1030109aba47SJacob Keller 	struct ice_pf *pf = vf->pf;
1031109aba47SJacob Keller 	struct ice_vsi *vsi;
1032109aba47SJacob Keller 
1033109aba47SJacob Keller 	vsi = ice_vsi_setup(pf, pi, ICE_VSI_CTRL, vf, NULL);
1034109aba47SJacob Keller 	if (!vsi) {
1035109aba47SJacob Keller 		dev_err(ice_pf_to_dev(pf), "Failed to create VF control VSI\n");
1036109aba47SJacob Keller 		ice_vf_ctrl_invalidate_vsi(vf);
1037109aba47SJacob Keller 	}
1038109aba47SJacob Keller 
1039109aba47SJacob Keller 	return vsi;
1040109aba47SJacob Keller }
1041109aba47SJacob Keller 
1042109aba47SJacob Keller /**
1043109aba47SJacob Keller  * ice_vf_invalidate_vsi - invalidate vsi_idx/vsi_num to remove VSI access
1044109aba47SJacob Keller  * @vf: VF to remove access to VSI for
1045109aba47SJacob Keller  */
1046109aba47SJacob Keller void ice_vf_invalidate_vsi(struct ice_vf *vf)
1047109aba47SJacob Keller {
1048109aba47SJacob Keller 	vf->lan_vsi_idx = ICE_NO_VSI;
1049109aba47SJacob Keller 	vf->lan_vsi_num = ICE_NO_VSI;
1050109aba47SJacob Keller }
1051109aba47SJacob Keller 
1052109aba47SJacob Keller /**
1053109aba47SJacob Keller  * ice_vf_set_initialized - VF is ready for VIRTCHNL communication
1054109aba47SJacob Keller  * @vf: VF to set in initialized state
1055109aba47SJacob Keller  *
1056109aba47SJacob Keller  * After this function the VF will be ready to receive/handle the
1057109aba47SJacob Keller  * VIRTCHNL_OP_GET_VF_RESOURCES message
1058109aba47SJacob Keller  */
1059109aba47SJacob Keller void ice_vf_set_initialized(struct ice_vf *vf)
1060109aba47SJacob Keller {
1061109aba47SJacob Keller 	ice_set_vf_state_qs_dis(vf);
1062109aba47SJacob Keller 	clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states);
1063109aba47SJacob Keller 	clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states);
1064109aba47SJacob Keller 	clear_bit(ICE_VF_STATE_DIS, vf->vf_states);
1065109aba47SJacob Keller 	set_bit(ICE_VF_STATE_INIT, vf->vf_states);
1066109aba47SJacob Keller 	memset(&vf->vlan_v2_caps, 0, sizeof(vf->vlan_v2_caps));
1067109aba47SJacob Keller }
1068