162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright (C) 2018-2020, Intel Corporation. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "ice.h"
562306a36Sopenharmony_ci#include "ice_fltr.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/**
862306a36Sopenharmony_ci * ice_fltr_free_list - free filter lists helper
962306a36Sopenharmony_ci * @dev: pointer to the device struct
1062306a36Sopenharmony_ci * @h: pointer to the list head to be freed
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Helper function to free filter lists previously created using
1362306a36Sopenharmony_ci * ice_fltr_add_mac_to_list
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_civoid ice_fltr_free_list(struct device *dev, struct list_head *h)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	struct ice_fltr_list_entry *e, *tmp;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	list_for_each_entry_safe(e, tmp, h, list_entry) {
2062306a36Sopenharmony_ci		list_del(&e->list_entry);
2162306a36Sopenharmony_ci		devm_kfree(dev, e);
2262306a36Sopenharmony_ci	}
2362306a36Sopenharmony_ci}
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/**
2662306a36Sopenharmony_ci * ice_fltr_add_entry_to_list - allocate and add filter entry to list
2762306a36Sopenharmony_ci * @dev: pointer to device needed by alloc function
2862306a36Sopenharmony_ci * @info: filter info struct that gets added to the passed in list
2962306a36Sopenharmony_ci * @list: pointer to the list which contains MAC filters entry
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_cistatic int
3262306a36Sopenharmony_ciice_fltr_add_entry_to_list(struct device *dev, struct ice_fltr_info *info,
3362306a36Sopenharmony_ci			   struct list_head *list)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	struct ice_fltr_list_entry *entry;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	entry = devm_kzalloc(dev, sizeof(*entry), GFP_ATOMIC);
3862306a36Sopenharmony_ci	if (!entry)
3962306a36Sopenharmony_ci		return -ENOMEM;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	entry->fltr_info = *info;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	INIT_LIST_HEAD(&entry->list_entry);
4462306a36Sopenharmony_ci	list_add(&entry->list_entry, list);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	return 0;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/**
5062306a36Sopenharmony_ci * ice_fltr_set_vlan_vsi_promisc
5162306a36Sopenharmony_ci * @hw: pointer to the hardware structure
5262306a36Sopenharmony_ci * @vsi: the VSI being configured
5362306a36Sopenharmony_ci * @promisc_mask: mask of promiscuous config bits
5462306a36Sopenharmony_ci *
5562306a36Sopenharmony_ci * Set VSI with all associated VLANs to given promiscuous mode(s)
5662306a36Sopenharmony_ci */
5762306a36Sopenharmony_ciint
5862306a36Sopenharmony_ciice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
5962306a36Sopenharmony_ci			      u8 promisc_mask)
6062306a36Sopenharmony_ci{
6162306a36Sopenharmony_ci	struct ice_pf *pf = hw->back;
6262306a36Sopenharmony_ci	int result;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
6562306a36Sopenharmony_ci	if (result && result != -EEXIST)
6662306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf),
6762306a36Sopenharmony_ci			"Error setting promisc mode on VSI %i (rc=%d)\n",
6862306a36Sopenharmony_ci			vsi->vsi_num, result);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	return result;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/**
7462306a36Sopenharmony_ci * ice_fltr_clear_vlan_vsi_promisc
7562306a36Sopenharmony_ci * @hw: pointer to the hardware structure
7662306a36Sopenharmony_ci * @vsi: the VSI being configured
7762306a36Sopenharmony_ci * @promisc_mask: mask of promiscuous config bits
7862306a36Sopenharmony_ci *
7962306a36Sopenharmony_ci * Clear VSI with all associated VLANs to given promiscuous mode(s)
8062306a36Sopenharmony_ci */
8162306a36Sopenharmony_ciint
8262306a36Sopenharmony_ciice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
8362306a36Sopenharmony_ci				u8 promisc_mask)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	struct ice_pf *pf = hw->back;
8662306a36Sopenharmony_ci	int result;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
8962306a36Sopenharmony_ci	if (result && result != -EEXIST)
9062306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf),
9162306a36Sopenharmony_ci			"Error clearing promisc mode on VSI %i (rc=%d)\n",
9262306a36Sopenharmony_ci			vsi->vsi_num, result);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	return result;
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/**
9862306a36Sopenharmony_ci * ice_fltr_clear_vsi_promisc - clear specified promiscuous mode(s)
9962306a36Sopenharmony_ci * @hw: pointer to the hardware structure
10062306a36Sopenharmony_ci * @vsi_handle: VSI handle to clear mode
10162306a36Sopenharmony_ci * @promisc_mask: mask of promiscuous config bits to clear
10262306a36Sopenharmony_ci * @vid: VLAN ID to clear VLAN promiscuous
10362306a36Sopenharmony_ci */
10462306a36Sopenharmony_ciint
10562306a36Sopenharmony_ciice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
10662306a36Sopenharmony_ci			   u16 vid)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	struct ice_pf *pf = hw->back;
10962306a36Sopenharmony_ci	int result;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
11262306a36Sopenharmony_ci	if (result && result != -EEXIST)
11362306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf),
11462306a36Sopenharmony_ci			"Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
11562306a36Sopenharmony_ci			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	return result;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/**
12162306a36Sopenharmony_ci * ice_fltr_set_vsi_promisc - set given VSI to given promiscuous mode(s)
12262306a36Sopenharmony_ci * @hw: pointer to the hardware structure
12362306a36Sopenharmony_ci * @vsi_handle: VSI handle to configure
12462306a36Sopenharmony_ci * @promisc_mask: mask of promiscuous config bits
12562306a36Sopenharmony_ci * @vid: VLAN ID to set VLAN promiscuous
12662306a36Sopenharmony_ci */
12762306a36Sopenharmony_ciint
12862306a36Sopenharmony_ciice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
12962306a36Sopenharmony_ci			 u16 vid)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	struct ice_pf *pf = hw->back;
13262306a36Sopenharmony_ci	int result;
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
13562306a36Sopenharmony_ci	if (result && result != -EEXIST)
13662306a36Sopenharmony_ci		dev_err(ice_pf_to_dev(pf),
13762306a36Sopenharmony_ci			"Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
13862306a36Sopenharmony_ci			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	return result;
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/**
14462306a36Sopenharmony_ci * ice_fltr_add_mac_list - add list of MAC filters
14562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
14662306a36Sopenharmony_ci * @list: list of filters
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_ciint ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	return ice_add_mac(&vsi->back->hw, list);
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/**
15462306a36Sopenharmony_ci * ice_fltr_remove_mac_list - remove list of MAC filters
15562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
15662306a36Sopenharmony_ci * @list: list of filters
15762306a36Sopenharmony_ci */
15862306a36Sopenharmony_ciint ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list)
15962306a36Sopenharmony_ci{
16062306a36Sopenharmony_ci	return ice_remove_mac(&vsi->back->hw, list);
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/**
16462306a36Sopenharmony_ci * ice_fltr_add_vlan_list - add list of VLAN filters
16562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
16662306a36Sopenharmony_ci * @list: list of filters
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_cistatic int ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	return ice_add_vlan(&vsi->back->hw, list);
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci/**
17462306a36Sopenharmony_ci * ice_fltr_remove_vlan_list - remove list of VLAN filters
17562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
17662306a36Sopenharmony_ci * @list: list of filters
17762306a36Sopenharmony_ci */
17862306a36Sopenharmony_cistatic int
17962306a36Sopenharmony_ciice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	return ice_remove_vlan(&vsi->back->hw, list);
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci/**
18562306a36Sopenharmony_ci * ice_fltr_add_eth_list - add list of ethertype filters
18662306a36Sopenharmony_ci * @vsi: pointer to VSI struct
18762306a36Sopenharmony_ci * @list: list of filters
18862306a36Sopenharmony_ci */
18962306a36Sopenharmony_cistatic int ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	return ice_add_eth_mac(&vsi->back->hw, list);
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci/**
19562306a36Sopenharmony_ci * ice_fltr_remove_eth_list - remove list of ethertype filters
19662306a36Sopenharmony_ci * @vsi: pointer to VSI struct
19762306a36Sopenharmony_ci * @list: list of filters
19862306a36Sopenharmony_ci */
19962306a36Sopenharmony_cistatic int ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	return ice_remove_eth_mac(&vsi->back->hw, list);
20262306a36Sopenharmony_ci}
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/**
20562306a36Sopenharmony_ci * ice_fltr_remove_all - remove all filters associated with VSI
20662306a36Sopenharmony_ci * @vsi: pointer to VSI struct
20762306a36Sopenharmony_ci */
20862306a36Sopenharmony_civoid ice_fltr_remove_all(struct ice_vsi *vsi)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
21162306a36Sopenharmony_ci	/* sync netdev filters if exist */
21262306a36Sopenharmony_ci	if (vsi->netdev) {
21362306a36Sopenharmony_ci		__dev_uc_unsync(vsi->netdev, NULL);
21462306a36Sopenharmony_ci		__dev_mc_unsync(vsi->netdev, NULL);
21562306a36Sopenharmony_ci	}
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/**
21962306a36Sopenharmony_ci * ice_fltr_add_mac_to_list - add MAC filter info to exsisting list
22062306a36Sopenharmony_ci * @vsi: pointer to VSI struct
22162306a36Sopenharmony_ci * @list: list to add filter info to
22262306a36Sopenharmony_ci * @mac: MAC address to add
22362306a36Sopenharmony_ci * @action: filter action
22462306a36Sopenharmony_ci */
22562306a36Sopenharmony_ciint
22662306a36Sopenharmony_ciice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
22762306a36Sopenharmony_ci			 const u8 *mac, enum ice_sw_fwd_act_type action)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci	struct ice_fltr_info info = { 0 };
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	info.flag = ICE_FLTR_TX;
23262306a36Sopenharmony_ci	info.src_id = ICE_SRC_ID_VSI;
23362306a36Sopenharmony_ci	info.lkup_type = ICE_SW_LKUP_MAC;
23462306a36Sopenharmony_ci	info.fltr_act = action;
23562306a36Sopenharmony_ci	info.vsi_handle = vsi->idx;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	ether_addr_copy(info.l_data.mac.mac_addr, mac);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
24062306a36Sopenharmony_ci					  list);
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci/**
24462306a36Sopenharmony_ci * ice_fltr_add_vlan_to_list - add VLAN filter info to exsisting list
24562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
24662306a36Sopenharmony_ci * @list: list to add filter info to
24762306a36Sopenharmony_ci * @vlan: VLAN filter details
24862306a36Sopenharmony_ci */
24962306a36Sopenharmony_cistatic int
25062306a36Sopenharmony_ciice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list,
25162306a36Sopenharmony_ci			  struct ice_vlan *vlan)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	struct ice_fltr_info info = { 0 };
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	info.flag = ICE_FLTR_TX;
25662306a36Sopenharmony_ci	info.src_id = ICE_SRC_ID_VSI;
25762306a36Sopenharmony_ci	info.lkup_type = ICE_SW_LKUP_VLAN;
25862306a36Sopenharmony_ci	info.fltr_act = ICE_FWD_TO_VSI;
25962306a36Sopenharmony_ci	info.vsi_handle = vsi->idx;
26062306a36Sopenharmony_ci	info.l_data.vlan.vlan_id = vlan->vid;
26162306a36Sopenharmony_ci	info.l_data.vlan.tpid = vlan->tpid;
26262306a36Sopenharmony_ci	info.l_data.vlan.tpid_valid = true;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
26562306a36Sopenharmony_ci					  list);
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/**
26962306a36Sopenharmony_ci * ice_fltr_add_eth_to_list - add ethertype filter info to exsisting list
27062306a36Sopenharmony_ci * @vsi: pointer to VSI struct
27162306a36Sopenharmony_ci * @list: list to add filter info to
27262306a36Sopenharmony_ci * @ethertype: ethertype of packet that matches filter
27362306a36Sopenharmony_ci * @flag: filter direction, Tx or Rx
27462306a36Sopenharmony_ci * @action: filter action
27562306a36Sopenharmony_ci */
27662306a36Sopenharmony_cistatic int
27762306a36Sopenharmony_ciice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list,
27862306a36Sopenharmony_ci			 u16 ethertype, u16 flag,
27962306a36Sopenharmony_ci			 enum ice_sw_fwd_act_type action)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	struct ice_fltr_info info = { 0 };
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	info.flag = flag;
28462306a36Sopenharmony_ci	info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
28562306a36Sopenharmony_ci	info.fltr_act = action;
28662306a36Sopenharmony_ci	info.vsi_handle = vsi->idx;
28762306a36Sopenharmony_ci	info.l_data.ethertype_mac.ethertype = ethertype;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	if (flag == ICE_FLTR_TX)
29062306a36Sopenharmony_ci		info.src_id = ICE_SRC_ID_VSI;
29162306a36Sopenharmony_ci	else
29262306a36Sopenharmony_ci		info.src_id = ICE_SRC_ID_LPORT;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
29562306a36Sopenharmony_ci					  list);
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci/**
29962306a36Sopenharmony_ci * ice_fltr_prepare_mac - add or remove MAC rule
30062306a36Sopenharmony_ci * @vsi: pointer to VSI struct
30162306a36Sopenharmony_ci * @mac: MAC address to add
30262306a36Sopenharmony_ci * @action: action to be performed on filter match
30362306a36Sopenharmony_ci * @mac_action: pointer to add or remove MAC function
30462306a36Sopenharmony_ci */
30562306a36Sopenharmony_cistatic int
30662306a36Sopenharmony_ciice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac,
30762306a36Sopenharmony_ci		     enum ice_sw_fwd_act_type action,
30862306a36Sopenharmony_ci		     int (*mac_action)(struct ice_vsi *, struct list_head *))
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	LIST_HEAD(tmp_list);
31162306a36Sopenharmony_ci	int result;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) {
31462306a36Sopenharmony_ci		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
31562306a36Sopenharmony_ci		return -ENOMEM;
31662306a36Sopenharmony_ci	}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	result = mac_action(vsi, &tmp_list);
31962306a36Sopenharmony_ci	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
32062306a36Sopenharmony_ci	return result;
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci/**
32462306a36Sopenharmony_ci * ice_fltr_prepare_mac_and_broadcast - add or remove MAC and broadcast filter
32562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
32662306a36Sopenharmony_ci * @mac: MAC address to add
32762306a36Sopenharmony_ci * @action: action to be performed on filter match
32862306a36Sopenharmony_ci * @mac_action: pointer to add or remove MAC function
32962306a36Sopenharmony_ci */
33062306a36Sopenharmony_cistatic int
33162306a36Sopenharmony_ciice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
33262306a36Sopenharmony_ci				   enum ice_sw_fwd_act_type action,
33362306a36Sopenharmony_ci				   int(*mac_action)
33462306a36Sopenharmony_ci				   (struct ice_vsi *, struct list_head *))
33562306a36Sopenharmony_ci{
33662306a36Sopenharmony_ci	u8 broadcast[ETH_ALEN];
33762306a36Sopenharmony_ci	LIST_HEAD(tmp_list);
33862306a36Sopenharmony_ci	int result;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	eth_broadcast_addr(broadcast);
34162306a36Sopenharmony_ci	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) ||
34262306a36Sopenharmony_ci	    ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) {
34362306a36Sopenharmony_ci		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
34462306a36Sopenharmony_ci		return -ENOMEM;
34562306a36Sopenharmony_ci	}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	result = mac_action(vsi, &tmp_list);
34862306a36Sopenharmony_ci	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
34962306a36Sopenharmony_ci	return result;
35062306a36Sopenharmony_ci}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci/**
35362306a36Sopenharmony_ci * ice_fltr_prepare_vlan - add or remove VLAN filter
35462306a36Sopenharmony_ci * @vsi: pointer to VSI struct
35562306a36Sopenharmony_ci * @vlan: VLAN filter details
35662306a36Sopenharmony_ci * @vlan_action: pointer to add or remove VLAN function
35762306a36Sopenharmony_ci */
35862306a36Sopenharmony_cistatic int
35962306a36Sopenharmony_ciice_fltr_prepare_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan,
36062306a36Sopenharmony_ci		      int (*vlan_action)(struct ice_vsi *, struct list_head *))
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	LIST_HEAD(tmp_list);
36362306a36Sopenharmony_ci	int result;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan))
36662306a36Sopenharmony_ci		return -ENOMEM;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	result = vlan_action(vsi, &tmp_list);
36962306a36Sopenharmony_ci	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
37062306a36Sopenharmony_ci	return result;
37162306a36Sopenharmony_ci}
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci/**
37462306a36Sopenharmony_ci * ice_fltr_prepare_eth - add or remove ethertype filter
37562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
37662306a36Sopenharmony_ci * @ethertype: ethertype of packet to be filtered
37762306a36Sopenharmony_ci * @flag: direction of packet, Tx or Rx
37862306a36Sopenharmony_ci * @action: action to be performed on filter match
37962306a36Sopenharmony_ci * @eth_action: pointer to add or remove ethertype function
38062306a36Sopenharmony_ci */
38162306a36Sopenharmony_cistatic int
38262306a36Sopenharmony_ciice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
38362306a36Sopenharmony_ci		     enum ice_sw_fwd_act_type action,
38462306a36Sopenharmony_ci		     int (*eth_action)(struct ice_vsi *, struct list_head *))
38562306a36Sopenharmony_ci{
38662306a36Sopenharmony_ci	LIST_HEAD(tmp_list);
38762306a36Sopenharmony_ci	int result;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action))
39062306a36Sopenharmony_ci		return -ENOMEM;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	result = eth_action(vsi, &tmp_list);
39362306a36Sopenharmony_ci	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
39462306a36Sopenharmony_ci	return result;
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci/**
39862306a36Sopenharmony_ci * ice_fltr_add_mac - add single MAC filter
39962306a36Sopenharmony_ci * @vsi: pointer to VSI struct
40062306a36Sopenharmony_ci * @mac: MAC to add
40162306a36Sopenharmony_ci * @action: action to be performed on filter match
40262306a36Sopenharmony_ci */
40362306a36Sopenharmony_ciint ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac,
40462306a36Sopenharmony_ci		     enum ice_sw_fwd_act_type action)
40562306a36Sopenharmony_ci{
40662306a36Sopenharmony_ci	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list);
40762306a36Sopenharmony_ci}
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci/**
41062306a36Sopenharmony_ci * ice_fltr_add_mac_and_broadcast - add single MAC and broadcast
41162306a36Sopenharmony_ci * @vsi: pointer to VSI struct
41262306a36Sopenharmony_ci * @mac: MAC to add
41362306a36Sopenharmony_ci * @action: action to be performed on filter match
41462306a36Sopenharmony_ci */
41562306a36Sopenharmony_ciint
41662306a36Sopenharmony_ciice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
41762306a36Sopenharmony_ci			       enum ice_sw_fwd_act_type action)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action,
42062306a36Sopenharmony_ci						  ice_fltr_add_mac_list);
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci/**
42462306a36Sopenharmony_ci * ice_fltr_remove_mac - remove MAC filter
42562306a36Sopenharmony_ci * @vsi: pointer to VSI struct
42662306a36Sopenharmony_ci * @mac: filter MAC to remove
42762306a36Sopenharmony_ci * @action: action to remove
42862306a36Sopenharmony_ci */
42962306a36Sopenharmony_ciint ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac,
43062306a36Sopenharmony_ci			enum ice_sw_fwd_act_type action)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list);
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci/**
43662306a36Sopenharmony_ci * ice_fltr_add_vlan - add single VLAN filter
43762306a36Sopenharmony_ci * @vsi: pointer to VSI struct
43862306a36Sopenharmony_ci * @vlan: VLAN filter details
43962306a36Sopenharmony_ci */
44062306a36Sopenharmony_ciint ice_fltr_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
44162306a36Sopenharmony_ci{
44262306a36Sopenharmony_ci	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_add_vlan_list);
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci/**
44662306a36Sopenharmony_ci * ice_fltr_remove_vlan - remove VLAN filter
44762306a36Sopenharmony_ci * @vsi: pointer to VSI struct
44862306a36Sopenharmony_ci * @vlan: VLAN filter details
44962306a36Sopenharmony_ci */
45062306a36Sopenharmony_ciint ice_fltr_remove_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
45162306a36Sopenharmony_ci{
45262306a36Sopenharmony_ci	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_remove_vlan_list);
45362306a36Sopenharmony_ci}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci/**
45662306a36Sopenharmony_ci * ice_fltr_add_eth - add specyfic ethertype filter
45762306a36Sopenharmony_ci * @vsi: pointer to VSI struct
45862306a36Sopenharmony_ci * @ethertype: ethertype of filter
45962306a36Sopenharmony_ci * @flag: direction of packet to be filtered, Tx or Rx
46062306a36Sopenharmony_ci * @action: action to be performed on filter match
46162306a36Sopenharmony_ci */
46262306a36Sopenharmony_ciint ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
46362306a36Sopenharmony_ci		     enum ice_sw_fwd_act_type action)
46462306a36Sopenharmony_ci{
46562306a36Sopenharmony_ci	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
46662306a36Sopenharmony_ci				    ice_fltr_add_eth_list);
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/**
47062306a36Sopenharmony_ci * ice_fltr_remove_eth - remove ethertype filter
47162306a36Sopenharmony_ci * @vsi: pointer to VSI struct
47262306a36Sopenharmony_ci * @ethertype: ethertype of filter
47362306a36Sopenharmony_ci * @flag: direction of filter
47462306a36Sopenharmony_ci * @action: action to remove
47562306a36Sopenharmony_ci */
47662306a36Sopenharmony_ciint ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
47762306a36Sopenharmony_ci			enum ice_sw_fwd_act_type action)
47862306a36Sopenharmony_ci{
47962306a36Sopenharmony_ci	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
48062306a36Sopenharmony_ci				    ice_fltr_remove_eth_list);
48162306a36Sopenharmony_ci}
482