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 */ 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 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 58fabf480bSBrett Creeley ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi, 59fabf480bSBrett Creeley u8 promisc_mask) 60fabf480bSBrett Creeley { 61fabf480bSBrett Creeley return ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false); 62fabf480bSBrett Creeley } 63fabf480bSBrett Creeley 64fabf480bSBrett Creeley /** 65fabf480bSBrett Creeley * ice_fltr_clear_vlan_vsi_promisc 66fabf480bSBrett Creeley * @hw: pointer to the hardware structure 67fabf480bSBrett Creeley * @vsi: the VSI being configured 68fabf480bSBrett Creeley * @promisc_mask: mask of promiscuous config bits 69fabf480bSBrett Creeley * 70fabf480bSBrett Creeley * Clear VSI with all associated VLANs to given promiscuous mode(s) 71fabf480bSBrett Creeley */ 725e24d598STony Nguyen int 73fabf480bSBrett Creeley ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi, 74fabf480bSBrett Creeley u8 promisc_mask) 75fabf480bSBrett Creeley { 76fabf480bSBrett Creeley return ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true); 77fabf480bSBrett Creeley } 78fabf480bSBrett Creeley 79fabf480bSBrett Creeley /** 80fabf480bSBrett Creeley * ice_fltr_clear_vsi_promisc - clear specified promiscuous mode(s) 81fabf480bSBrett Creeley * @hw: pointer to the hardware structure 82fabf480bSBrett Creeley * @vsi_handle: VSI handle to clear mode 83fabf480bSBrett Creeley * @promisc_mask: mask of promiscuous config bits to clear 84fabf480bSBrett Creeley * @vid: VLAN ID to clear VLAN promiscuous 85fabf480bSBrett Creeley */ 865e24d598STony Nguyen int 87fabf480bSBrett Creeley ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 88fabf480bSBrett Creeley u16 vid) 89fabf480bSBrett Creeley { 90fabf480bSBrett Creeley return ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid); 91fabf480bSBrett Creeley } 92fabf480bSBrett Creeley 93fabf480bSBrett Creeley /** 94fabf480bSBrett Creeley * ice_fltr_set_vsi_promisc - set given VSI to given promiscuous mode(s) 95fabf480bSBrett Creeley * @hw: pointer to the hardware structure 96fabf480bSBrett Creeley * @vsi_handle: VSI handle to configure 97fabf480bSBrett Creeley * @promisc_mask: mask of promiscuous config bits 98fabf480bSBrett Creeley * @vid: VLAN ID to set VLAN promiscuous 99fabf480bSBrett Creeley */ 1005e24d598STony Nguyen int 101fabf480bSBrett Creeley ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 102fabf480bSBrett Creeley u16 vid) 103fabf480bSBrett Creeley { 104fabf480bSBrett Creeley return ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid); 105fabf480bSBrett Creeley } 106fabf480bSBrett Creeley 107fabf480bSBrett Creeley /** 1081b8f15b6SMichal Swiatkowski * ice_fltr_add_mac_list - add list of MAC filters 1091b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1101b8f15b6SMichal Swiatkowski * @list: list of filters 1111b8f15b6SMichal Swiatkowski */ 1125e24d598STony Nguyen int 1131b8f15b6SMichal Swiatkowski ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list) 1141b8f15b6SMichal Swiatkowski { 1151b8f15b6SMichal Swiatkowski return ice_add_mac(&vsi->back->hw, list); 1161b8f15b6SMichal Swiatkowski } 1171b8f15b6SMichal Swiatkowski 1181b8f15b6SMichal Swiatkowski /** 1191b8f15b6SMichal Swiatkowski * ice_fltr_remove_mac_list - remove list of MAC filters 1201b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1211b8f15b6SMichal Swiatkowski * @list: list of filters 1221b8f15b6SMichal Swiatkowski */ 1235e24d598STony Nguyen int 1241b8f15b6SMichal Swiatkowski ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list) 1251b8f15b6SMichal Swiatkowski { 1261b8f15b6SMichal Swiatkowski return ice_remove_mac(&vsi->back->hw, list); 1271b8f15b6SMichal Swiatkowski } 1281b8f15b6SMichal Swiatkowski 1291b8f15b6SMichal Swiatkowski /** 1301b8f15b6SMichal Swiatkowski * ice_fltr_add_vlan_list - add list of VLAN filters 1311b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1321b8f15b6SMichal Swiatkowski * @list: list of filters 1331b8f15b6SMichal Swiatkowski */ 1345e24d598STony Nguyen static int 1351b8f15b6SMichal Swiatkowski ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list) 1361b8f15b6SMichal Swiatkowski { 1371b8f15b6SMichal Swiatkowski return ice_add_vlan(&vsi->back->hw, list); 1381b8f15b6SMichal Swiatkowski } 1391b8f15b6SMichal Swiatkowski 1401b8f15b6SMichal Swiatkowski /** 1411b8f15b6SMichal Swiatkowski * ice_fltr_remove_vlan_list - remove list of VLAN filters 1421b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1431b8f15b6SMichal Swiatkowski * @list: list of filters 1441b8f15b6SMichal Swiatkowski */ 1455e24d598STony Nguyen static int 1461b8f15b6SMichal Swiatkowski ice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list) 1471b8f15b6SMichal Swiatkowski { 1481b8f15b6SMichal Swiatkowski return ice_remove_vlan(&vsi->back->hw, list); 1491b8f15b6SMichal Swiatkowski } 1501b8f15b6SMichal Swiatkowski 1511b8f15b6SMichal Swiatkowski /** 1521b8f15b6SMichal Swiatkowski * ice_fltr_add_eth_list - add list of ethertype filters 1531b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1541b8f15b6SMichal Swiatkowski * @list: list of filters 1551b8f15b6SMichal Swiatkowski */ 1565e24d598STony Nguyen static int 1571b8f15b6SMichal Swiatkowski ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list) 1581b8f15b6SMichal Swiatkowski { 1591b8f15b6SMichal Swiatkowski return ice_add_eth_mac(&vsi->back->hw, list); 1601b8f15b6SMichal Swiatkowski } 1611b8f15b6SMichal Swiatkowski 1621b8f15b6SMichal Swiatkowski /** 1631b8f15b6SMichal Swiatkowski * ice_fltr_remove_eth_list - remove list of ethertype filters 1641b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1651b8f15b6SMichal Swiatkowski * @list: list of filters 1661b8f15b6SMichal Swiatkowski */ 1675e24d598STony Nguyen static int 1681b8f15b6SMichal Swiatkowski ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list) 1691b8f15b6SMichal Swiatkowski { 1701b8f15b6SMichal Swiatkowski return ice_remove_eth_mac(&vsi->back->hw, list); 1711b8f15b6SMichal Swiatkowski } 1721b8f15b6SMichal Swiatkowski 1731b8f15b6SMichal Swiatkowski /** 1741b8f15b6SMichal Swiatkowski * ice_fltr_remove_all - remove all filters associated with VSI 1751b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1761b8f15b6SMichal Swiatkowski */ 1771b8f15b6SMichal Swiatkowski void ice_fltr_remove_all(struct ice_vsi *vsi) 1781b8f15b6SMichal Swiatkowski { 1791b8f15b6SMichal Swiatkowski ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx); 1801b8f15b6SMichal Swiatkowski } 1811b8f15b6SMichal Swiatkowski 1821b8f15b6SMichal Swiatkowski /** 1831b8f15b6SMichal Swiatkowski * ice_fltr_add_mac_to_list - add MAC filter info to exsisting list 1841b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 1851b8f15b6SMichal Swiatkowski * @list: list to add filter info to 1861b8f15b6SMichal Swiatkowski * @mac: MAC address to add 1871b8f15b6SMichal Swiatkowski * @action: filter action 1881b8f15b6SMichal Swiatkowski */ 1891b8f15b6SMichal Swiatkowski int 1901b8f15b6SMichal Swiatkowski ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list, 1911b8f15b6SMichal Swiatkowski const u8 *mac, enum ice_sw_fwd_act_type action) 1921b8f15b6SMichal Swiatkowski { 1931b8f15b6SMichal Swiatkowski struct ice_fltr_info info = { 0 }; 1941b8f15b6SMichal Swiatkowski 1951b8f15b6SMichal Swiatkowski info.flag = ICE_FLTR_TX; 1961b8f15b6SMichal Swiatkowski info.src_id = ICE_SRC_ID_VSI; 1971b8f15b6SMichal Swiatkowski info.lkup_type = ICE_SW_LKUP_MAC; 1981b8f15b6SMichal Swiatkowski info.fltr_act = action; 1991b8f15b6SMichal Swiatkowski info.vsi_handle = vsi->idx; 2001b8f15b6SMichal Swiatkowski 2011b8f15b6SMichal Swiatkowski ether_addr_copy(info.l_data.mac.mac_addr, mac); 2021b8f15b6SMichal Swiatkowski 2031b8f15b6SMichal Swiatkowski return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info, 2041b8f15b6SMichal Swiatkowski list); 2051b8f15b6SMichal Swiatkowski } 2061b8f15b6SMichal Swiatkowski 2071b8f15b6SMichal Swiatkowski /** 2081b8f15b6SMichal Swiatkowski * ice_fltr_add_vlan_to_list - add VLAN filter info to exsisting list 2091b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 2101b8f15b6SMichal Swiatkowski * @list: list to add filter info to 2111b8f15b6SMichal Swiatkowski * @vlan_id: VLAN ID to add 2121b8f15b6SMichal Swiatkowski * @action: filter action 2131b8f15b6SMichal Swiatkowski */ 2141b8f15b6SMichal Swiatkowski static int 2151b8f15b6SMichal Swiatkowski ice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list, 2161b8f15b6SMichal Swiatkowski u16 vlan_id, enum ice_sw_fwd_act_type action) 2171b8f15b6SMichal Swiatkowski { 2181b8f15b6SMichal Swiatkowski struct ice_fltr_info info = { 0 }; 2191b8f15b6SMichal Swiatkowski 2201b8f15b6SMichal Swiatkowski info.flag = ICE_FLTR_TX; 2211b8f15b6SMichal Swiatkowski info.src_id = ICE_SRC_ID_VSI; 2221b8f15b6SMichal Swiatkowski info.lkup_type = ICE_SW_LKUP_VLAN; 2231b8f15b6SMichal Swiatkowski info.fltr_act = action; 2241b8f15b6SMichal Swiatkowski info.vsi_handle = vsi->idx; 2251b8f15b6SMichal Swiatkowski info.l_data.vlan.vlan_id = vlan_id; 2261b8f15b6SMichal Swiatkowski 2271b8f15b6SMichal Swiatkowski return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info, 2281b8f15b6SMichal Swiatkowski list); 2291b8f15b6SMichal Swiatkowski } 2301b8f15b6SMichal Swiatkowski 2311b8f15b6SMichal Swiatkowski /** 2321b8f15b6SMichal Swiatkowski * ice_fltr_add_eth_to_list - add ethertype filter info to exsisting list 2331b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 2341b8f15b6SMichal Swiatkowski * @list: list to add filter info to 2351b8f15b6SMichal Swiatkowski * @ethertype: ethertype of packet that matches filter 2361b8f15b6SMichal Swiatkowski * @flag: filter direction, Tx or Rx 2371b8f15b6SMichal Swiatkowski * @action: filter action 2381b8f15b6SMichal Swiatkowski */ 2391b8f15b6SMichal Swiatkowski static int 2401b8f15b6SMichal Swiatkowski ice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list, 2411b8f15b6SMichal Swiatkowski u16 ethertype, u16 flag, 2421b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 2431b8f15b6SMichal Swiatkowski { 2441b8f15b6SMichal Swiatkowski struct ice_fltr_info info = { 0 }; 2451b8f15b6SMichal Swiatkowski 2461b8f15b6SMichal Swiatkowski info.flag = flag; 2471b8f15b6SMichal Swiatkowski info.lkup_type = ICE_SW_LKUP_ETHERTYPE; 2481b8f15b6SMichal Swiatkowski info.fltr_act = action; 2491b8f15b6SMichal Swiatkowski info.vsi_handle = vsi->idx; 2501b8f15b6SMichal Swiatkowski info.l_data.ethertype_mac.ethertype = ethertype; 2511b8f15b6SMichal Swiatkowski 2521b8f15b6SMichal Swiatkowski if (flag == ICE_FLTR_TX) 2531b8f15b6SMichal Swiatkowski info.src_id = ICE_SRC_ID_VSI; 2541b8f15b6SMichal Swiatkowski else 2551b8f15b6SMichal Swiatkowski info.src_id = ICE_SRC_ID_LPORT; 2561b8f15b6SMichal Swiatkowski 2571b8f15b6SMichal Swiatkowski return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info, 2581b8f15b6SMichal Swiatkowski list); 2591b8f15b6SMichal Swiatkowski } 2601b8f15b6SMichal Swiatkowski 2611b8f15b6SMichal Swiatkowski /** 2621b8f15b6SMichal Swiatkowski * ice_fltr_prepare_mac - add or remove MAC rule 2631b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 2641b8f15b6SMichal Swiatkowski * @mac: MAC address to add 2651b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 2661b8f15b6SMichal Swiatkowski * @mac_action: pointer to add or remove MAC function 2671b8f15b6SMichal Swiatkowski */ 2685e24d598STony Nguyen static int 2691b8f15b6SMichal Swiatkowski ice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac, 2701b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action, 2715e24d598STony Nguyen int (*mac_action)(struct ice_vsi *, struct list_head *)) 2721b8f15b6SMichal Swiatkowski { 2735e24d598STony Nguyen int result; 2741b8f15b6SMichal Swiatkowski LIST_HEAD(tmp_list); 2751b8f15b6SMichal Swiatkowski 2761b8f15b6SMichal Swiatkowski if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) { 2771b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 278*d54699e2STony Nguyen return -ENOMEM; 2791b8f15b6SMichal Swiatkowski } 2801b8f15b6SMichal Swiatkowski 2811b8f15b6SMichal Swiatkowski result = mac_action(vsi, &tmp_list); 2821b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 2831b8f15b6SMichal Swiatkowski return result; 2841b8f15b6SMichal Swiatkowski } 2851b8f15b6SMichal Swiatkowski 2861b8f15b6SMichal Swiatkowski /** 2871b8f15b6SMichal Swiatkowski * ice_fltr_prepare_mac_and_broadcast - add or remove MAC and broadcast filter 2881b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 2891b8f15b6SMichal Swiatkowski * @mac: MAC address to add 2901b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 2911b8f15b6SMichal Swiatkowski * @mac_action: pointer to add or remove MAC function 2921b8f15b6SMichal Swiatkowski */ 2935e24d598STony Nguyen static int 2941b8f15b6SMichal Swiatkowski ice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac, 2951b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action, 2965e24d598STony Nguyen int(*mac_action) 2971b8f15b6SMichal Swiatkowski (struct ice_vsi *, struct list_head *)) 2981b8f15b6SMichal Swiatkowski { 2991b8f15b6SMichal Swiatkowski u8 broadcast[ETH_ALEN]; 3005e24d598STony Nguyen int result; 3011b8f15b6SMichal Swiatkowski LIST_HEAD(tmp_list); 3021b8f15b6SMichal Swiatkowski 3031b8f15b6SMichal Swiatkowski eth_broadcast_addr(broadcast); 3041b8f15b6SMichal Swiatkowski if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) || 3051b8f15b6SMichal Swiatkowski ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) { 3061b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 307*d54699e2STony Nguyen return -ENOMEM; 3081b8f15b6SMichal Swiatkowski } 3091b8f15b6SMichal Swiatkowski 3101b8f15b6SMichal Swiatkowski result = mac_action(vsi, &tmp_list); 3111b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 3121b8f15b6SMichal Swiatkowski return result; 3131b8f15b6SMichal Swiatkowski } 3141b8f15b6SMichal Swiatkowski 3151b8f15b6SMichal Swiatkowski /** 3161b8f15b6SMichal Swiatkowski * ice_fltr_prepare_vlan - add or remove VLAN filter 3171b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 3181b8f15b6SMichal Swiatkowski * @vlan_id: VLAN ID to add 3191b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 3201b8f15b6SMichal Swiatkowski * @vlan_action: pointer to add or remove VLAN function 3211b8f15b6SMichal Swiatkowski */ 3225e24d598STony Nguyen static int 3231b8f15b6SMichal Swiatkowski ice_fltr_prepare_vlan(struct ice_vsi *vsi, u16 vlan_id, 3241b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action, 3255e24d598STony Nguyen int (*vlan_action)(struct ice_vsi *, struct list_head *)) 3261b8f15b6SMichal Swiatkowski { 3275e24d598STony Nguyen int result; 3281b8f15b6SMichal Swiatkowski LIST_HEAD(tmp_list); 3291b8f15b6SMichal Swiatkowski 3301b8f15b6SMichal Swiatkowski if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan_id, action)) 331*d54699e2STony Nguyen return -ENOMEM; 3321b8f15b6SMichal Swiatkowski 3331b8f15b6SMichal Swiatkowski result = vlan_action(vsi, &tmp_list); 3341b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 3351b8f15b6SMichal Swiatkowski return result; 3361b8f15b6SMichal Swiatkowski } 3371b8f15b6SMichal Swiatkowski 3381b8f15b6SMichal Swiatkowski /** 3391b8f15b6SMichal Swiatkowski * ice_fltr_prepare_eth - add or remove ethertype filter 3401b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 3411b8f15b6SMichal Swiatkowski * @ethertype: ethertype of packet to be filtered 3421b8f15b6SMichal Swiatkowski * @flag: direction of packet, Tx or Rx 3431b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 3441b8f15b6SMichal Swiatkowski * @eth_action: pointer to add or remove ethertype function 3451b8f15b6SMichal Swiatkowski */ 3465e24d598STony Nguyen static int 3471b8f15b6SMichal Swiatkowski ice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag, 3481b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action, 3495e24d598STony Nguyen int (*eth_action)(struct ice_vsi *, struct list_head *)) 3501b8f15b6SMichal Swiatkowski { 3515e24d598STony Nguyen int result; 3521b8f15b6SMichal Swiatkowski LIST_HEAD(tmp_list); 3531b8f15b6SMichal Swiatkowski 3541b8f15b6SMichal Swiatkowski if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action)) 355*d54699e2STony Nguyen return -ENOMEM; 3561b8f15b6SMichal Swiatkowski 3571b8f15b6SMichal Swiatkowski result = eth_action(vsi, &tmp_list); 3581b8f15b6SMichal Swiatkowski ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list); 3591b8f15b6SMichal Swiatkowski return result; 3601b8f15b6SMichal Swiatkowski } 3611b8f15b6SMichal Swiatkowski 3621b8f15b6SMichal Swiatkowski /** 3631b8f15b6SMichal Swiatkowski * ice_fltr_add_mac - add single MAC filter 3641b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 3651b8f15b6SMichal Swiatkowski * @mac: MAC to add 3661b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 3671b8f15b6SMichal Swiatkowski */ 3685e24d598STony Nguyen int ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac, 3691b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 3701b8f15b6SMichal Swiatkowski { 3711b8f15b6SMichal Swiatkowski return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list); 3721b8f15b6SMichal Swiatkowski } 3731b8f15b6SMichal Swiatkowski 3741b8f15b6SMichal Swiatkowski /** 3751b8f15b6SMichal Swiatkowski * ice_fltr_add_mac_and_broadcast - add single MAC and broadcast 3761b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 3771b8f15b6SMichal Swiatkowski * @mac: MAC to add 3781b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 3791b8f15b6SMichal Swiatkowski */ 3805e24d598STony Nguyen int 3811b8f15b6SMichal Swiatkowski ice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac, 3821b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 3831b8f15b6SMichal Swiatkowski { 3841b8f15b6SMichal Swiatkowski return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action, 3851b8f15b6SMichal Swiatkowski ice_fltr_add_mac_list); 3861b8f15b6SMichal Swiatkowski } 3871b8f15b6SMichal Swiatkowski 3881b8f15b6SMichal Swiatkowski /** 3891b8f15b6SMichal Swiatkowski * ice_fltr_remove_mac - remove MAC filter 3901b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 3911b8f15b6SMichal Swiatkowski * @mac: filter MAC to remove 3921b8f15b6SMichal Swiatkowski * @action: action to remove 3931b8f15b6SMichal Swiatkowski */ 3945e24d598STony Nguyen int ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac, 3951b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 3961b8f15b6SMichal Swiatkowski { 3971b8f15b6SMichal Swiatkowski return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list); 3981b8f15b6SMichal Swiatkowski } 3991b8f15b6SMichal Swiatkowski 4001b8f15b6SMichal Swiatkowski /** 4011b8f15b6SMichal Swiatkowski * ice_fltr_add_vlan - add single VLAN filter 4021b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 4031b8f15b6SMichal Swiatkowski * @vlan_id: VLAN ID to add 4041b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 4051b8f15b6SMichal Swiatkowski */ 4065e24d598STony Nguyen int ice_fltr_add_vlan(struct ice_vsi *vsi, u16 vlan_id, 4071b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 4081b8f15b6SMichal Swiatkowski { 4091b8f15b6SMichal Swiatkowski return ice_fltr_prepare_vlan(vsi, vlan_id, action, 4101b8f15b6SMichal Swiatkowski ice_fltr_add_vlan_list); 4111b8f15b6SMichal Swiatkowski } 4121b8f15b6SMichal Swiatkowski 4131b8f15b6SMichal Swiatkowski /** 4141b8f15b6SMichal Swiatkowski * ice_fltr_remove_vlan - remove VLAN filter 4151b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 4161b8f15b6SMichal Swiatkowski * @vlan_id: filter VLAN to remove 4171b8f15b6SMichal Swiatkowski * @action: action to remove 4181b8f15b6SMichal Swiatkowski */ 4195e24d598STony Nguyen int ice_fltr_remove_vlan(struct ice_vsi *vsi, u16 vlan_id, 4201b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 4211b8f15b6SMichal Swiatkowski { 4221b8f15b6SMichal Swiatkowski return ice_fltr_prepare_vlan(vsi, vlan_id, action, 4231b8f15b6SMichal Swiatkowski ice_fltr_remove_vlan_list); 4241b8f15b6SMichal Swiatkowski } 4251b8f15b6SMichal Swiatkowski 4261b8f15b6SMichal Swiatkowski /** 4271b8f15b6SMichal Swiatkowski * ice_fltr_add_eth - add specyfic ethertype filter 4281b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 4291b8f15b6SMichal Swiatkowski * @ethertype: ethertype of filter 4301b8f15b6SMichal Swiatkowski * @flag: direction of packet to be filtered, Tx or Rx 4311b8f15b6SMichal Swiatkowski * @action: action to be performed on filter match 4321b8f15b6SMichal Swiatkowski */ 4335e24d598STony Nguyen int ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag, 4341b8f15b6SMichal Swiatkowski enum ice_sw_fwd_act_type action) 4351b8f15b6SMichal Swiatkowski { 4361b8f15b6SMichal Swiatkowski return ice_fltr_prepare_eth(vsi, ethertype, flag, action, 4371b8f15b6SMichal Swiatkowski ice_fltr_add_eth_list); 4381b8f15b6SMichal Swiatkowski } 4391b8f15b6SMichal Swiatkowski 4401b8f15b6SMichal Swiatkowski /** 4411b8f15b6SMichal Swiatkowski * ice_fltr_remove_eth - remove ethertype filter 4421b8f15b6SMichal Swiatkowski * @vsi: pointer to VSI struct 4431b8f15b6SMichal Swiatkowski * @ethertype: ethertype of filter 4441b8f15b6SMichal Swiatkowski * @flag: direction of filter 4451b8f15b6SMichal Swiatkowski * @action: action to remove 4461b8f15b6SMichal Swiatkowski */ 4475e24d598STony Nguyen int ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag, 4485e24d598STony Nguyen enum ice_sw_fwd_act_type action) 4491b8f15b6SMichal Swiatkowski { 4501b8f15b6SMichal Swiatkowski return ice_fltr_prepare_eth(vsi, ethertype, flag, action, 4511b8f15b6SMichal Swiatkowski ice_fltr_remove_eth_list); 4521b8f15b6SMichal Swiatkowski } 453bd676b29SMichal Swiatkowski 454bd676b29SMichal Swiatkowski /** 455bd676b29SMichal Swiatkowski * ice_fltr_update_rule_flags - update lan_en/lb_en flags 456bd676b29SMichal Swiatkowski * @hw: pointer to hw 457bd676b29SMichal Swiatkowski * @rule_id: id of rule being updated 458bd676b29SMichal Swiatkowski * @recipe_id: recipe id of rule 459bd676b29SMichal Swiatkowski * @act: current action field 460bd676b29SMichal Swiatkowski * @type: Rx or Tx 461bd676b29SMichal Swiatkowski * @src: source VSI 462bd676b29SMichal Swiatkowski * @new_flags: combinations of lb_en and lan_en 463bd676b29SMichal Swiatkowski */ 4645e24d598STony Nguyen static int 465bd676b29SMichal Swiatkowski ice_fltr_update_rule_flags(struct ice_hw *hw, u16 rule_id, u16 recipe_id, 466bd676b29SMichal Swiatkowski u32 act, u16 type, u16 src, u32 new_flags) 467bd676b29SMichal Swiatkowski { 468bd676b29SMichal Swiatkowski struct ice_aqc_sw_rules_elem *s_rule; 4695e24d598STony Nguyen int err; 470bd676b29SMichal Swiatkowski u32 flags_mask; 471bd676b29SMichal Swiatkowski 472bd676b29SMichal Swiatkowski s_rule = kzalloc(ICE_SW_RULE_RX_TX_NO_HDR_SIZE, GFP_KERNEL); 473bd676b29SMichal Swiatkowski if (!s_rule) 474*d54699e2STony Nguyen return -ENOMEM; 475bd676b29SMichal Swiatkowski 476bd676b29SMichal Swiatkowski flags_mask = ICE_SINGLE_ACT_LB_ENABLE | ICE_SINGLE_ACT_LAN_ENABLE; 477bd676b29SMichal Swiatkowski act &= ~flags_mask; 478bd676b29SMichal Swiatkowski act |= (flags_mask & new_flags); 479bd676b29SMichal Swiatkowski 480bd676b29SMichal Swiatkowski s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(recipe_id); 481bd676b29SMichal Swiatkowski s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(rule_id); 482bd676b29SMichal Swiatkowski s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act); 483bd676b29SMichal Swiatkowski 484bd676b29SMichal Swiatkowski if (type & ICE_FLTR_RX) { 485bd676b29SMichal Swiatkowski s_rule->pdata.lkup_tx_rx.src = 486bd676b29SMichal Swiatkowski cpu_to_le16(hw->port_info->lport); 487bd676b29SMichal Swiatkowski s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX); 488bd676b29SMichal Swiatkowski 489bd676b29SMichal Swiatkowski } else { 490bd676b29SMichal Swiatkowski s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(src); 491bd676b29SMichal Swiatkowski s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 492bd676b29SMichal Swiatkowski } 493bd676b29SMichal Swiatkowski 494bd676b29SMichal Swiatkowski err = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1, 495bd676b29SMichal Swiatkowski ice_aqc_opc_update_sw_rules, NULL); 496bd676b29SMichal Swiatkowski 497bd676b29SMichal Swiatkowski kfree(s_rule); 498bd676b29SMichal Swiatkowski return err; 499bd676b29SMichal Swiatkowski } 500bd676b29SMichal Swiatkowski 501bd676b29SMichal Swiatkowski /** 502bd676b29SMichal Swiatkowski * ice_fltr_build_action - build action for rule 503bd676b29SMichal Swiatkowski * @vsi_id: id of VSI which is use to build action 504bd676b29SMichal Swiatkowski */ 505bd676b29SMichal Swiatkowski static u32 ice_fltr_build_action(u16 vsi_id) 506bd676b29SMichal Swiatkowski { 507bd676b29SMichal Swiatkowski return ((vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M) | 508bd676b29SMichal Swiatkowski ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 509bd676b29SMichal Swiatkowski } 510bd676b29SMichal Swiatkowski 511bd676b29SMichal Swiatkowski /** 512bd676b29SMichal Swiatkowski * ice_fltr_update_flags_dflt_rule - update flags on default rule 513bd676b29SMichal Swiatkowski * @vsi: pointer to VSI 514bd676b29SMichal Swiatkowski * @rule_id: id of rule 515bd676b29SMichal Swiatkowski * @direction: Tx or Rx 516bd676b29SMichal Swiatkowski * @new_flags: flags to update 517bd676b29SMichal Swiatkowski * 518bd676b29SMichal Swiatkowski * Function updates flags on default rule with ICE_SW_LKUP_DFLT. 519bd676b29SMichal Swiatkowski * 520bd676b29SMichal Swiatkowski * Flags should be a combination of ICE_SINGLE_ACT_LB_ENABLE and 521bd676b29SMichal Swiatkowski * ICE_SINGLE_ACT_LAN_ENABLE. 522bd676b29SMichal Swiatkowski */ 5235e24d598STony Nguyen int 524bd676b29SMichal Swiatkowski ice_fltr_update_flags_dflt_rule(struct ice_vsi *vsi, u16 rule_id, u8 direction, 525bd676b29SMichal Swiatkowski u32 new_flags) 526bd676b29SMichal Swiatkowski { 527bd676b29SMichal Swiatkowski u32 action = ice_fltr_build_action(vsi->vsi_num); 528bd676b29SMichal Swiatkowski struct ice_hw *hw = &vsi->back->hw; 529bd676b29SMichal Swiatkowski 530bd676b29SMichal Swiatkowski return ice_fltr_update_rule_flags(hw, rule_id, ICE_SW_LKUP_DFLT, action, 531bd676b29SMichal Swiatkowski direction, vsi->vsi_num, new_flags); 532bd676b29SMichal Swiatkowski } 533