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