11b8f15b6SMichal Swiatkowski // SPDX-License-Identifier: GPL-2.0
21b8f15b6SMichal Swiatkowski /* Copyright (C) 2018-2020, Intel Corporation. */
31b8f15b6SMichal Swiatkowski 
41b8f15b6SMichal Swiatkowski #include "ice.h"
51b8f15b6SMichal Swiatkowski #include "ice_fltr.h"
61b8f15b6SMichal Swiatkowski 
71b8f15b6SMichal Swiatkowski /**
81b8f15b6SMichal Swiatkowski  * ice_fltr_free_list - free filter lists helper
91b8f15b6SMichal Swiatkowski  * @dev: pointer to the device struct
101b8f15b6SMichal Swiatkowski  * @h: pointer to the list head to be freed
111b8f15b6SMichal Swiatkowski  *
121b8f15b6SMichal Swiatkowski  * Helper function to free filter lists previously created using
131b8f15b6SMichal Swiatkowski  * ice_fltr_add_mac_to_list
141b8f15b6SMichal Swiatkowski  */
ice_fltr_free_list(struct device * dev,struct list_head * h)151b8f15b6SMichal Swiatkowski void ice_fltr_free_list(struct device *dev, struct list_head *h)
161b8f15b6SMichal Swiatkowski {
171b8f15b6SMichal Swiatkowski 	struct ice_fltr_list_entry *e, *tmp;
181b8f15b6SMichal Swiatkowski 
191b8f15b6SMichal Swiatkowski 	list_for_each_entry_safe(e, tmp, h, list_entry) {
201b8f15b6SMichal Swiatkowski 		list_del(&e->list_entry);
211b8f15b6SMichal Swiatkowski 		devm_kfree(dev, e);
221b8f15b6SMichal Swiatkowski 	}
231b8f15b6SMichal Swiatkowski }
241b8f15b6SMichal Swiatkowski 
251b8f15b6SMichal Swiatkowski /**
261b8f15b6SMichal Swiatkowski  * ice_fltr_add_entry_to_list - allocate and add filter entry to list
271b8f15b6SMichal Swiatkowski  * @dev: pointer to device needed by alloc function
281b8f15b6SMichal Swiatkowski  * @info: filter info struct that gets added to the passed in list
291b8f15b6SMichal Swiatkowski  * @list: pointer to the list which contains MAC filters entry
301b8f15b6SMichal Swiatkowski  */
311b8f15b6SMichal Swiatkowski static int
ice_fltr_add_entry_to_list(struct device * dev,struct ice_fltr_info * info,struct list_head * list)321b8f15b6SMichal Swiatkowski ice_fltr_add_entry_to_list(struct device *dev, struct ice_fltr_info *info,
331b8f15b6SMichal Swiatkowski 			   struct list_head *list)
341b8f15b6SMichal Swiatkowski {
351b8f15b6SMichal Swiatkowski 	struct ice_fltr_list_entry *entry;
361b8f15b6SMichal Swiatkowski 
371b8f15b6SMichal Swiatkowski 	entry = devm_kzalloc(dev, sizeof(*entry), GFP_ATOMIC);
381b8f15b6SMichal Swiatkowski 	if (!entry)
391b8f15b6SMichal Swiatkowski 		return -ENOMEM;
401b8f15b6SMichal Swiatkowski 
411b8f15b6SMichal Swiatkowski 	entry->fltr_info = *info;
421b8f15b6SMichal Swiatkowski 
431b8f15b6SMichal Swiatkowski 	INIT_LIST_HEAD(&entry->list_entry);
441b8f15b6SMichal Swiatkowski 	list_add(&entry->list_entry, list);
451b8f15b6SMichal Swiatkowski 
461b8f15b6SMichal Swiatkowski 	return 0;
471b8f15b6SMichal Swiatkowski }
481b8f15b6SMichal Swiatkowski 
491b8f15b6SMichal Swiatkowski /**
50fabf480bSBrett Creeley  * ice_fltr_set_vlan_vsi_promisc
51fabf480bSBrett Creeley  * @hw: pointer to the hardware structure
52fabf480bSBrett Creeley  * @vsi: the VSI being configured
53fabf480bSBrett Creeley  * @promisc_mask: mask of promiscuous config bits
54fabf480bSBrett Creeley  *
55fabf480bSBrett Creeley  * Set VSI with all associated VLANs to given promiscuous mode(s)
56fabf480bSBrett Creeley  */
575e24d598STony Nguyen int
ice_fltr_set_vlan_vsi_promisc(struct ice_hw * hw,struct ice_vsi * vsi,u8 promisc_mask)58fabf480bSBrett Creeley ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
59fabf480bSBrett Creeley 			      u8 promisc_mask)
60fabf480bSBrett Creeley {
611273f895SIvan Vecera 	struct ice_pf *pf = hw->back;
621273f895SIvan Vecera 	int result;
631273f895SIvan Vecera 
641273f895SIvan Vecera 	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
6579956b83SBenjamin Mikailenko 	if (result && result != -EEXIST)
661273f895SIvan Vecera 		dev_err(ice_pf_to_dev(pf),
671273f895SIvan Vecera 			"Error setting promisc mode on VSI %i (rc=%d)\n",
681273f895SIvan Vecera 			vsi->vsi_num, result);
691273f895SIvan Vecera 
701273f895SIvan Vecera 	return result;
71fabf480bSBrett Creeley }
72fabf480bSBrett Creeley 
73fabf480bSBrett Creeley /**
74fabf480bSBrett Creeley  * ice_fltr_clear_vlan_vsi_promisc
75fabf480bSBrett Creeley  * @hw: pointer to the hardware structure
76fabf480bSBrett Creeley  * @vsi: the VSI being configured
77fabf480bSBrett Creeley  * @promisc_mask: mask of promiscuous config bits
78fabf480bSBrett Creeley  *
79fabf480bSBrett Creeley  * Clear VSI with all associated VLANs to given promiscuous mode(s)
80fabf480bSBrett Creeley  */
815e24d598STony Nguyen int
ice_fltr_clear_vlan_vsi_promisc(struct ice_hw * hw,struct ice_vsi * vsi,u8 promisc_mask)82fabf480bSBrett Creeley ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
83fabf480bSBrett Creeley 				u8 promisc_mask)
84fabf480bSBrett Creeley {
851273f895SIvan Vecera 	struct ice_pf *pf = hw->back;
861273f895SIvan Vecera 	int result;
871273f895SIvan Vecera 
881273f895SIvan Vecera 	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
8979956b83SBenjamin Mikailenko 	if (result && result != -EEXIST)
901273f895SIvan Vecera 		dev_err(ice_pf_to_dev(pf),
911273f895SIvan Vecera 			"Error clearing promisc mode on VSI %i (rc=%d)\n",
921273f895SIvan Vecera 			vsi->vsi_num, result);
931273f895SIvan Vecera 
941273f895SIvan Vecera 	return result;
95fabf480bSBrett Creeley }
96fabf480bSBrett Creeley 
97fabf480bSBrett Creeley /**
98fabf480bSBrett Creeley  * ice_fltr_clear_vsi_promisc - clear specified promiscuous mode(s)
99fabf480bSBrett Creeley  * @hw: pointer to the hardware structure
100fabf480bSBrett Creeley  * @vsi_handle: VSI handle to clear mode
101fabf480bSBrett Creeley  * @promisc_mask: mask of promiscuous config bits to clear
102fabf480bSBrett Creeley  * @vid: VLAN ID to clear VLAN promiscuous
103fabf480bSBrett Creeley  */
1045e24d598STony Nguyen int
ice_fltr_clear_vsi_promisc(struct ice_hw * hw,u16 vsi_handle,u8 promisc_mask,u16 vid)105fabf480bSBrett Creeley ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
106fabf480bSBrett Creeley 			   u16 vid)
107fabf480bSBrett Creeley {
1081273f895SIvan Vecera 	struct ice_pf *pf = hw->back;
1091273f895SIvan Vecera 	int result;
1101273f895SIvan Vecera 
1111273f895SIvan Vecera 	result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
11279956b83SBenjamin Mikailenko 	if (result && result != -EEXIST)
1131273f895SIvan Vecera 		dev_err(ice_pf_to_dev(pf),
1141273f895SIvan Vecera 			"Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
1151273f895SIvan Vecera 			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
1161273f895SIvan Vecera 
1171273f895SIvan Vecera 	return result;
118fabf480bSBrett Creeley }
119fabf480bSBrett Creeley 
120fabf480bSBrett Creeley /**
121fabf480bSBrett Creeley  * ice_fltr_set_vsi_promisc - set given VSI to given promiscuous mode(s)
122fabf480bSBrett Creeley  * @hw: pointer to the hardware structure
123fabf480bSBrett Creeley  * @vsi_handle: VSI handle to configure
124fabf480bSBrett Creeley  * @promisc_mask: mask of promiscuous config bits
125fabf480bSBrett Creeley  * @vid: VLAN ID to set VLAN promiscuous
126fabf480bSBrett Creeley  */
1275e24d598STony Nguyen int
ice_fltr_set_vsi_promisc(struct ice_hw * hw,u16 vsi_handle,u8 promisc_mask,u16 vid)128fabf480bSBrett Creeley ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
129fabf480bSBrett Creeley 			 u16 vid)
130fabf480bSBrett Creeley {
1311273f895SIvan Vecera 	struct ice_pf *pf = hw->back;
1321273f895SIvan Vecera 	int result;
1331273f895SIvan Vecera 
1341273f895SIvan Vecera 	result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
13579956b83SBenjamin Mikailenko 	if (result && result != -EEXIST)
1361273f895SIvan Vecera 		dev_err(ice_pf_to_dev(pf),
1371273f895SIvan Vecera 			"Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
1381273f895SIvan Vecera 			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
1391273f895SIvan Vecera 
1401273f895SIvan Vecera 	return result;
141fabf480bSBrett Creeley }
142fabf480bSBrett Creeley 
143fabf480bSBrett Creeley /**
1441b8f15b6SMichal Swiatkowski  * ice_fltr_add_mac_list - add list of MAC filters
1451b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1461b8f15b6SMichal Swiatkowski  * @list: list of filters
1471b8f15b6SMichal Swiatkowski  */
ice_fltr_add_mac_list(struct ice_vsi * vsi,struct list_head * list)1485518ac2aSTony Nguyen int ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list)
1491b8f15b6SMichal Swiatkowski {
1501b8f15b6SMichal Swiatkowski 	return ice_add_mac(&vsi->back->hw, list);
1511b8f15b6SMichal Swiatkowski }
1521b8f15b6SMichal Swiatkowski 
1531b8f15b6SMichal Swiatkowski /**
1541b8f15b6SMichal Swiatkowski  * ice_fltr_remove_mac_list - remove list of MAC filters
1551b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1561b8f15b6SMichal Swiatkowski  * @list: list of filters
1571b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_mac_list(struct ice_vsi * vsi,struct list_head * list)1585518ac2aSTony Nguyen int ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list)
1591b8f15b6SMichal Swiatkowski {
1601b8f15b6SMichal Swiatkowski 	return ice_remove_mac(&vsi->back->hw, list);
1611b8f15b6SMichal Swiatkowski }
1621b8f15b6SMichal Swiatkowski 
1631b8f15b6SMichal Swiatkowski /**
1641b8f15b6SMichal Swiatkowski  * ice_fltr_add_vlan_list - add list of VLAN filters
1651b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1661b8f15b6SMichal Swiatkowski  * @list: list of filters
1671b8f15b6SMichal Swiatkowski  */
ice_fltr_add_vlan_list(struct ice_vsi * vsi,struct list_head * list)1685518ac2aSTony Nguyen static int ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list)
1691b8f15b6SMichal Swiatkowski {
1701b8f15b6SMichal Swiatkowski 	return ice_add_vlan(&vsi->back->hw, list);
1711b8f15b6SMichal Swiatkowski }
1721b8f15b6SMichal Swiatkowski 
1731b8f15b6SMichal Swiatkowski /**
1741b8f15b6SMichal Swiatkowski  * ice_fltr_remove_vlan_list - remove list of VLAN filters
1751b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1761b8f15b6SMichal Swiatkowski  * @list: list of filters
1771b8f15b6SMichal Swiatkowski  */
1785e24d598STony Nguyen static int
ice_fltr_remove_vlan_list(struct ice_vsi * vsi,struct list_head * list)1791b8f15b6SMichal Swiatkowski ice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list)
1801b8f15b6SMichal Swiatkowski {
1811b8f15b6SMichal Swiatkowski 	return ice_remove_vlan(&vsi->back->hw, list);
1821b8f15b6SMichal Swiatkowski }
1831b8f15b6SMichal Swiatkowski 
1841b8f15b6SMichal Swiatkowski /**
1851b8f15b6SMichal Swiatkowski  * ice_fltr_add_eth_list - add list of ethertype filters
1861b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1871b8f15b6SMichal Swiatkowski  * @list: list of filters
1881b8f15b6SMichal Swiatkowski  */
ice_fltr_add_eth_list(struct ice_vsi * vsi,struct list_head * list)1895518ac2aSTony Nguyen static int ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list)
1901b8f15b6SMichal Swiatkowski {
1911b8f15b6SMichal Swiatkowski 	return ice_add_eth_mac(&vsi->back->hw, list);
1921b8f15b6SMichal Swiatkowski }
1931b8f15b6SMichal Swiatkowski 
1941b8f15b6SMichal Swiatkowski /**
1951b8f15b6SMichal Swiatkowski  * ice_fltr_remove_eth_list - remove list of ethertype filters
1961b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
1971b8f15b6SMichal Swiatkowski  * @list: list of filters
1981b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_eth_list(struct ice_vsi * vsi,struct list_head * list)1995518ac2aSTony Nguyen static int ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
2001b8f15b6SMichal Swiatkowski {
2011b8f15b6SMichal Swiatkowski 	return ice_remove_eth_mac(&vsi->back->hw, list);
2021b8f15b6SMichal Swiatkowski }
2031b8f15b6SMichal Swiatkowski 
2041b8f15b6SMichal Swiatkowski /**
2051b8f15b6SMichal Swiatkowski  * ice_fltr_remove_all - remove all filters associated with VSI
2061b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
2071b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_all(struct ice_vsi * vsi)2081b8f15b6SMichal Swiatkowski void ice_fltr_remove_all(struct ice_vsi *vsi)
2091b8f15b6SMichal Swiatkowski {
2101b8f15b6SMichal Swiatkowski 	ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
211*70fbc15aSMichal Swiatkowski 	/* sync netdev filters if exist */
212*70fbc15aSMichal Swiatkowski 	if (vsi->netdev) {
213*70fbc15aSMichal Swiatkowski 		__dev_uc_unsync(vsi->netdev, NULL);
214*70fbc15aSMichal Swiatkowski 		__dev_mc_unsync(vsi->netdev, NULL);
215*70fbc15aSMichal Swiatkowski 	}
2161b8f15b6SMichal Swiatkowski }
2171b8f15b6SMichal Swiatkowski 
2181b8f15b6SMichal Swiatkowski /**
2191b8f15b6SMichal Swiatkowski  * ice_fltr_add_mac_to_list - add MAC filter info to exsisting list
2201b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
2211b8f15b6SMichal Swiatkowski  * @list: list to add filter info to
2221b8f15b6SMichal Swiatkowski  * @mac: MAC address to add
2231b8f15b6SMichal Swiatkowski  * @action: filter action
2241b8f15b6SMichal Swiatkowski  */
2251b8f15b6SMichal Swiatkowski int
ice_fltr_add_mac_to_list(struct ice_vsi * vsi,struct list_head * list,const u8 * mac,enum ice_sw_fwd_act_type action)2261b8f15b6SMichal Swiatkowski ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
2271b8f15b6SMichal Swiatkowski 			 const u8 *mac, enum ice_sw_fwd_act_type action)
2281b8f15b6SMichal Swiatkowski {
2291b8f15b6SMichal Swiatkowski 	struct ice_fltr_info info = { 0 };
2301b8f15b6SMichal Swiatkowski 
2311b8f15b6SMichal Swiatkowski 	info.flag = ICE_FLTR_TX;
2321b8f15b6SMichal Swiatkowski 	info.src_id = ICE_SRC_ID_VSI;
2331b8f15b6SMichal Swiatkowski 	info.lkup_type = ICE_SW_LKUP_MAC;
2341b8f15b6SMichal Swiatkowski 	info.fltr_act = action;
2351b8f15b6SMichal Swiatkowski 	info.vsi_handle = vsi->idx;
2361b8f15b6SMichal Swiatkowski 
2371b8f15b6SMichal Swiatkowski 	ether_addr_copy(info.l_data.mac.mac_addr, mac);
2381b8f15b6SMichal Swiatkowski 
2391b8f15b6SMichal Swiatkowski 	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
2401b8f15b6SMichal Swiatkowski 					  list);
2411b8f15b6SMichal Swiatkowski }
2421b8f15b6SMichal Swiatkowski 
2431b8f15b6SMichal Swiatkowski /**
2441b8f15b6SMichal Swiatkowski  * ice_fltr_add_vlan_to_list - add VLAN filter info to exsisting list
2451b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
2461b8f15b6SMichal Swiatkowski  * @list: list to add filter info to
247fb05ba12SBrett Creeley  * @vlan: VLAN filter details
2481b8f15b6SMichal Swiatkowski  */
2491b8f15b6SMichal Swiatkowski static int
ice_fltr_add_vlan_to_list(struct ice_vsi * vsi,struct list_head * list,struct ice_vlan * vlan)2501b8f15b6SMichal Swiatkowski ice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list,
251fb05ba12SBrett Creeley 			  struct ice_vlan *vlan)
2521b8f15b6SMichal Swiatkowski {
2531b8f15b6SMichal Swiatkowski 	struct ice_fltr_info info = { 0 };
2541b8f15b6SMichal Swiatkowski 
2551b8f15b6SMichal Swiatkowski 	info.flag = ICE_FLTR_TX;
2561b8f15b6SMichal Swiatkowski 	info.src_id = ICE_SRC_ID_VSI;
2571b8f15b6SMichal Swiatkowski 	info.lkup_type = ICE_SW_LKUP_VLAN;
258fb05ba12SBrett Creeley 	info.fltr_act = ICE_FWD_TO_VSI;
2591b8f15b6SMichal Swiatkowski 	info.vsi_handle = vsi->idx;
260fb05ba12SBrett Creeley 	info.l_data.vlan.vlan_id = vlan->vid;
2612bfefa2dSBrett Creeley 	info.l_data.vlan.tpid = vlan->tpid;
2622bfefa2dSBrett Creeley 	info.l_data.vlan.tpid_valid = true;
2631b8f15b6SMichal Swiatkowski 
2641b8f15b6SMichal Swiatkowski 	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
2651b8f15b6SMichal Swiatkowski 					  list);
2661b8f15b6SMichal Swiatkowski }
2671b8f15b6SMichal Swiatkowski 
2681b8f15b6SMichal Swiatkowski /**
2691b8f15b6SMichal Swiatkowski  * ice_fltr_add_eth_to_list - add ethertype filter info to exsisting list
2701b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
2711b8f15b6SMichal Swiatkowski  * @list: list to add filter info to
2721b8f15b6SMichal Swiatkowski  * @ethertype: ethertype of packet that matches filter
2731b8f15b6SMichal Swiatkowski  * @flag: filter direction, Tx or Rx
2741b8f15b6SMichal Swiatkowski  * @action: filter action
2751b8f15b6SMichal Swiatkowski  */
2761b8f15b6SMichal Swiatkowski static int
ice_fltr_add_eth_to_list(struct ice_vsi * vsi,struct list_head * list,u16 ethertype,u16 flag,enum ice_sw_fwd_act_type action)2771b8f15b6SMichal Swiatkowski ice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list,
2781b8f15b6SMichal Swiatkowski 			 u16 ethertype, u16 flag,
2791b8f15b6SMichal Swiatkowski 			 enum ice_sw_fwd_act_type action)
2801b8f15b6SMichal Swiatkowski {
2811b8f15b6SMichal Swiatkowski 	struct ice_fltr_info info = { 0 };
2821b8f15b6SMichal Swiatkowski 
2831b8f15b6SMichal Swiatkowski 	info.flag = flag;
2841b8f15b6SMichal Swiatkowski 	info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
2851b8f15b6SMichal Swiatkowski 	info.fltr_act = action;
2861b8f15b6SMichal Swiatkowski 	info.vsi_handle = vsi->idx;
2871b8f15b6SMichal Swiatkowski 	info.l_data.ethertype_mac.ethertype = ethertype;
2881b8f15b6SMichal Swiatkowski 
2891b8f15b6SMichal Swiatkowski 	if (flag == ICE_FLTR_TX)
2901b8f15b6SMichal Swiatkowski 		info.src_id = ICE_SRC_ID_VSI;
2911b8f15b6SMichal Swiatkowski 	else
2921b8f15b6SMichal Swiatkowski 		info.src_id = ICE_SRC_ID_LPORT;
2931b8f15b6SMichal Swiatkowski 
2941b8f15b6SMichal Swiatkowski 	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
2951b8f15b6SMichal Swiatkowski 					  list);
2961b8f15b6SMichal Swiatkowski }
2971b8f15b6SMichal Swiatkowski 
2981b8f15b6SMichal Swiatkowski /**
2991b8f15b6SMichal Swiatkowski  * ice_fltr_prepare_mac - add or remove MAC rule
3001b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
3011b8f15b6SMichal Swiatkowski  * @mac: MAC address to add
3021b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
3031b8f15b6SMichal Swiatkowski  * @mac_action: pointer to add or remove MAC function
3041b8f15b6SMichal Swiatkowski  */
3055e24d598STony Nguyen static int
ice_fltr_prepare_mac(struct ice_vsi * vsi,const u8 * mac,enum ice_sw_fwd_act_type action,int (* mac_action)(struct ice_vsi *,struct list_head *))3061b8f15b6SMichal Swiatkowski ice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac,
3071b8f15b6SMichal Swiatkowski 		     enum ice_sw_fwd_act_type action,
3085e24d598STony Nguyen 		     int (*mac_action)(struct ice_vsi *, struct list_head *))
3091b8f15b6SMichal Swiatkowski {
3101b8f15b6SMichal Swiatkowski 	LIST_HEAD(tmp_list);
3115518ac2aSTony Nguyen 	int result;
3121b8f15b6SMichal Swiatkowski 
3131b8f15b6SMichal Swiatkowski 	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) {
3141b8f15b6SMichal Swiatkowski 		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
315d54699e2STony Nguyen 		return -ENOMEM;
3161b8f15b6SMichal Swiatkowski 	}
3171b8f15b6SMichal Swiatkowski 
3181b8f15b6SMichal Swiatkowski 	result = mac_action(vsi, &tmp_list);
3191b8f15b6SMichal Swiatkowski 	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
3201b8f15b6SMichal Swiatkowski 	return result;
3211b8f15b6SMichal Swiatkowski }
3221b8f15b6SMichal Swiatkowski 
3231b8f15b6SMichal Swiatkowski /**
3241b8f15b6SMichal Swiatkowski  * ice_fltr_prepare_mac_and_broadcast - add or remove MAC and broadcast filter
3251b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
3261b8f15b6SMichal Swiatkowski  * @mac: MAC address to add
3271b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
3281b8f15b6SMichal Swiatkowski  * @mac_action: pointer to add or remove MAC function
3291b8f15b6SMichal Swiatkowski  */
3305e24d598STony Nguyen static int
ice_fltr_prepare_mac_and_broadcast(struct ice_vsi * vsi,const u8 * mac,enum ice_sw_fwd_act_type action,int (* mac_action)(struct ice_vsi *,struct list_head *))3311b8f15b6SMichal Swiatkowski ice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
3321b8f15b6SMichal Swiatkowski 				   enum ice_sw_fwd_act_type action,
3335e24d598STony Nguyen 				   int(*mac_action)
3341b8f15b6SMichal Swiatkowski 				   (struct ice_vsi *, struct list_head *))
3351b8f15b6SMichal Swiatkowski {
3361b8f15b6SMichal Swiatkowski 	u8 broadcast[ETH_ALEN];
3371b8f15b6SMichal Swiatkowski 	LIST_HEAD(tmp_list);
3385518ac2aSTony Nguyen 	int result;
3391b8f15b6SMichal Swiatkowski 
3401b8f15b6SMichal Swiatkowski 	eth_broadcast_addr(broadcast);
3411b8f15b6SMichal Swiatkowski 	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) ||
3421b8f15b6SMichal Swiatkowski 	    ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) {
3431b8f15b6SMichal Swiatkowski 		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
344d54699e2STony Nguyen 		return -ENOMEM;
3451b8f15b6SMichal Swiatkowski 	}
3461b8f15b6SMichal Swiatkowski 
3471b8f15b6SMichal Swiatkowski 	result = mac_action(vsi, &tmp_list);
3481b8f15b6SMichal Swiatkowski 	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
3491b8f15b6SMichal Swiatkowski 	return result;
3501b8f15b6SMichal Swiatkowski }
3511b8f15b6SMichal Swiatkowski 
3521b8f15b6SMichal Swiatkowski /**
3531b8f15b6SMichal Swiatkowski  * ice_fltr_prepare_vlan - add or remove VLAN filter
3541b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
355fb05ba12SBrett Creeley  * @vlan: VLAN filter details
3561b8f15b6SMichal Swiatkowski  * @vlan_action: pointer to add or remove VLAN function
3571b8f15b6SMichal Swiatkowski  */
3585e24d598STony Nguyen static int
ice_fltr_prepare_vlan(struct ice_vsi * vsi,struct ice_vlan * vlan,int (* vlan_action)(struct ice_vsi *,struct list_head *))359fb05ba12SBrett Creeley ice_fltr_prepare_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan,
3605e24d598STony Nguyen 		      int (*vlan_action)(struct ice_vsi *, struct list_head *))
3611b8f15b6SMichal Swiatkowski {
3621b8f15b6SMichal Swiatkowski 	LIST_HEAD(tmp_list);
3635518ac2aSTony Nguyen 	int result;
3641b8f15b6SMichal Swiatkowski 
365fb05ba12SBrett Creeley 	if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan))
366d54699e2STony Nguyen 		return -ENOMEM;
3671b8f15b6SMichal Swiatkowski 
3681b8f15b6SMichal Swiatkowski 	result = vlan_action(vsi, &tmp_list);
3691b8f15b6SMichal Swiatkowski 	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
3701b8f15b6SMichal Swiatkowski 	return result;
3711b8f15b6SMichal Swiatkowski }
3721b8f15b6SMichal Swiatkowski 
3731b8f15b6SMichal Swiatkowski /**
3741b8f15b6SMichal Swiatkowski  * ice_fltr_prepare_eth - add or remove ethertype filter
3751b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
3761b8f15b6SMichal Swiatkowski  * @ethertype: ethertype of packet to be filtered
3771b8f15b6SMichal Swiatkowski  * @flag: direction of packet, Tx or Rx
3781b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
3791b8f15b6SMichal Swiatkowski  * @eth_action: pointer to add or remove ethertype function
3801b8f15b6SMichal Swiatkowski  */
3815e24d598STony Nguyen static int
ice_fltr_prepare_eth(struct ice_vsi * vsi,u16 ethertype,u16 flag,enum ice_sw_fwd_act_type action,int (* eth_action)(struct ice_vsi *,struct list_head *))3821b8f15b6SMichal Swiatkowski ice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
3831b8f15b6SMichal Swiatkowski 		     enum ice_sw_fwd_act_type action,
3845e24d598STony Nguyen 		     int (*eth_action)(struct ice_vsi *, struct list_head *))
3851b8f15b6SMichal Swiatkowski {
3861b8f15b6SMichal Swiatkowski 	LIST_HEAD(tmp_list);
3875518ac2aSTony Nguyen 	int result;
3881b8f15b6SMichal Swiatkowski 
3891b8f15b6SMichal Swiatkowski 	if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action))
390d54699e2STony Nguyen 		return -ENOMEM;
3911b8f15b6SMichal Swiatkowski 
3921b8f15b6SMichal Swiatkowski 	result = eth_action(vsi, &tmp_list);
3931b8f15b6SMichal Swiatkowski 	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
3941b8f15b6SMichal Swiatkowski 	return result;
3951b8f15b6SMichal Swiatkowski }
3961b8f15b6SMichal Swiatkowski 
3971b8f15b6SMichal Swiatkowski /**
3981b8f15b6SMichal Swiatkowski  * ice_fltr_add_mac - add single MAC filter
3991b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
4001b8f15b6SMichal Swiatkowski  * @mac: MAC to add
4011b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
4021b8f15b6SMichal Swiatkowski  */
ice_fltr_add_mac(struct ice_vsi * vsi,const u8 * mac,enum ice_sw_fwd_act_type action)4035e24d598STony Nguyen int ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac,
4041b8f15b6SMichal Swiatkowski 		     enum ice_sw_fwd_act_type action)
4051b8f15b6SMichal Swiatkowski {
4061b8f15b6SMichal Swiatkowski 	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list);
4071b8f15b6SMichal Swiatkowski }
4081b8f15b6SMichal Swiatkowski 
4091b8f15b6SMichal Swiatkowski /**
4101b8f15b6SMichal Swiatkowski  * ice_fltr_add_mac_and_broadcast - add single MAC and broadcast
4111b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
4121b8f15b6SMichal Swiatkowski  * @mac: MAC to add
4131b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
4141b8f15b6SMichal Swiatkowski  */
4155e24d598STony Nguyen int
ice_fltr_add_mac_and_broadcast(struct ice_vsi * vsi,const u8 * mac,enum ice_sw_fwd_act_type action)4161b8f15b6SMichal Swiatkowski ice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
4171b8f15b6SMichal Swiatkowski 			       enum ice_sw_fwd_act_type action)
4181b8f15b6SMichal Swiatkowski {
4191b8f15b6SMichal Swiatkowski 	return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action,
4201b8f15b6SMichal Swiatkowski 						  ice_fltr_add_mac_list);
4211b8f15b6SMichal Swiatkowski }
4221b8f15b6SMichal Swiatkowski 
4231b8f15b6SMichal Swiatkowski /**
4241b8f15b6SMichal Swiatkowski  * ice_fltr_remove_mac - remove MAC filter
4251b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
4261b8f15b6SMichal Swiatkowski  * @mac: filter MAC to remove
4271b8f15b6SMichal Swiatkowski  * @action: action to remove
4281b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_mac(struct ice_vsi * vsi,const u8 * mac,enum ice_sw_fwd_act_type action)4295e24d598STony Nguyen int ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac,
4301b8f15b6SMichal Swiatkowski 			enum ice_sw_fwd_act_type action)
4311b8f15b6SMichal Swiatkowski {
4321b8f15b6SMichal Swiatkowski 	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list);
4331b8f15b6SMichal Swiatkowski }
4341b8f15b6SMichal Swiatkowski 
4351b8f15b6SMichal Swiatkowski /**
4361b8f15b6SMichal Swiatkowski  * ice_fltr_add_vlan - add single VLAN filter
4371b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
438fb05ba12SBrett Creeley  * @vlan: VLAN filter details
4391b8f15b6SMichal Swiatkowski  */
ice_fltr_add_vlan(struct ice_vsi * vsi,struct ice_vlan * vlan)440fb05ba12SBrett Creeley int ice_fltr_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
4411b8f15b6SMichal Swiatkowski {
442fb05ba12SBrett Creeley 	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_add_vlan_list);
4431b8f15b6SMichal Swiatkowski }
4441b8f15b6SMichal Swiatkowski 
4451b8f15b6SMichal Swiatkowski /**
4461b8f15b6SMichal Swiatkowski  * ice_fltr_remove_vlan - remove VLAN filter
4471b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
448fb05ba12SBrett Creeley  * @vlan: VLAN filter details
4491b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_vlan(struct ice_vsi * vsi,struct ice_vlan * vlan)450fb05ba12SBrett Creeley int ice_fltr_remove_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
4511b8f15b6SMichal Swiatkowski {
452fb05ba12SBrett Creeley 	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_remove_vlan_list);
4531b8f15b6SMichal Swiatkowski }
4541b8f15b6SMichal Swiatkowski 
4551b8f15b6SMichal Swiatkowski /**
4561b8f15b6SMichal Swiatkowski  * ice_fltr_add_eth - add specyfic ethertype filter
4571b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
4581b8f15b6SMichal Swiatkowski  * @ethertype: ethertype of filter
4591b8f15b6SMichal Swiatkowski  * @flag: direction of packet to be filtered, Tx or Rx
4601b8f15b6SMichal Swiatkowski  * @action: action to be performed on filter match
4611b8f15b6SMichal Swiatkowski  */
ice_fltr_add_eth(struct ice_vsi * vsi,u16 ethertype,u16 flag,enum ice_sw_fwd_act_type action)4625e24d598STony Nguyen int ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
4631b8f15b6SMichal Swiatkowski 		     enum ice_sw_fwd_act_type action)
4641b8f15b6SMichal Swiatkowski {
4651b8f15b6SMichal Swiatkowski 	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
4661b8f15b6SMichal Swiatkowski 				    ice_fltr_add_eth_list);
4671b8f15b6SMichal Swiatkowski }
4681b8f15b6SMichal Swiatkowski 
4691b8f15b6SMichal Swiatkowski /**
4701b8f15b6SMichal Swiatkowski  * ice_fltr_remove_eth - remove ethertype filter
4711b8f15b6SMichal Swiatkowski  * @vsi: pointer to VSI struct
4721b8f15b6SMichal Swiatkowski  * @ethertype: ethertype of filter
4731b8f15b6SMichal Swiatkowski  * @flag: direction of filter
4741b8f15b6SMichal Swiatkowski  * @action: action to remove
4751b8f15b6SMichal Swiatkowski  */
ice_fltr_remove_eth(struct ice_vsi * vsi,u16 ethertype,u16 flag,enum ice_sw_fwd_act_type action)4765e24d598STony Nguyen int ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
4775e24d598STony Nguyen 			enum ice_sw_fwd_act_type action)
4781b8f15b6SMichal Swiatkowski {
4791b8f15b6SMichal Swiatkowski 	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
4801b8f15b6SMichal Swiatkowski 				    ice_fltr_remove_eth_list);
4811b8f15b6SMichal Swiatkowski }
482