// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, Intel Corporation. */ #include "ice_lib.h" #include "ice_switch.h" #include "ice_trace.h" #define ICE_ETH_DA_OFFSET … #define ICE_ETH_ETHTYPE_OFFSET … #define ICE_ETH_VLAN_TCI_OFFSET … #define ICE_MAX_VLAN_ID … #define ICE_IPV6_ETHER_ID … /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem * struct to configure any switch filter rules. * {DA (6 bytes), SA(6 bytes), * Ether type (2 bytes for header without VLAN tag) OR * VLAN tag (4 bytes for header with VLAN tag) } * * Word on Hardcoded values * byte 0 = 0x2: to identify it as locally administered DA MAC * byte 6 = 0x2: to identify it as locally administered SA MAC * byte 12 = 0x81 & byte 13 = 0x00: * In case of VLAN filter first two bytes defines ether type (0x8100) * and remaining two bytes are placeholder for programming a given VLAN ID * In case of Ether type filter it is treated as header without VLAN tag * and byte 12 and 13 is used to program a given Ether type instead */ static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = …; enum { … }; struct ice_dummy_pkt_offsets { … }; struct ice_dummy_pkt_profile { … }; #define ICE_DECLARE_PKT_OFFSETS(type) … #define ICE_DECLARE_PKT_TEMPLATE(type) … #define ICE_PKT_PROFILE(type, m) … ICE_DECLARE_PKT_OFFSETS(vlan) = …; ICE_DECLARE_PKT_TEMPLATE(vlan) = …; ICE_DECLARE_PKT_OFFSETS(qinq) = …; ICE_DECLARE_PKT_TEMPLATE(qinq) = …; ICE_DECLARE_PKT_OFFSETS(gre_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = …; ICE_DECLARE_PKT_OFFSETS(gre_udp) = …; ICE_DECLARE_PKT_TEMPLATE(gre_udp) = …; ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = …; ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = …; ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = …; ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = …; ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = …; ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = …; ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = …; ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = …; ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = …; /* offset info for MAC + IPv4 + UDP dummy packet */ ICE_DECLARE_PKT_OFFSETS(udp) = …; /* Dummy packet for MAC + IPv4 + UDP */ ICE_DECLARE_PKT_TEMPLATE(udp) = …; /* offset info for MAC + IPv4 + TCP dummy packet */ ICE_DECLARE_PKT_OFFSETS(tcp) = …; /* Dummy packet for MAC + IPv4 + TCP */ ICE_DECLARE_PKT_TEMPLATE(tcp) = …; ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = …; ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = …; /* IPv6 + UDP */ ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = …; /* IPv6 + UDP dummy packet */ ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = …; /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = …; /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */ ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = …; /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = …; ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = …; ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = …; ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv4) = …; ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv4) = …; ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv6) = …; ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv6) = …; ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = …; ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = …; ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = …; ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = …; ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = …; ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = …; ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = …; ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = …; ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = …; ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = …; ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = …; static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = …; /* this is a recipe to profile association bitmap */ static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES], ICE_MAX_NUM_PROFILES); /* this is a profile to recipe association bitmap */ static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES], ICE_MAX_NUM_RECIPES); /** * ice_init_def_sw_recp - initialize the recipe book keeping tables * @hw: pointer to the HW struct * * Allocate memory for the entire recipe table and initialize the structures/ * entries corresponding to basic recipes. */ int ice_init_def_sw_recp(struct ice_hw *hw) { … } /** * ice_aq_get_sw_cfg - get switch configuration * @hw: pointer to the hardware structure * @buf: pointer to the result buffer * @buf_size: length of the buffer available for response * @req_desc: pointer to requested descriptor * @num_elems: pointer to number of elements * @cd: pointer to command details structure or NULL * * Get switch configuration (0x0200) to be placed in buf. * This admin command returns information such as initial VSI/port number * and switch ID it belongs to. * * NOTE: *req_desc is both an input/output parameter. * The caller of this function first calls this function with *request_desc set * to 0. If the response from f/w has *req_desc set to 0, all the switch * configuration information has been returned; if non-zero (meaning not all * the information was returned), the caller should call this function again * with *req_desc set to the previous value returned by f/w to get the * next block of switch configuration information. * * *num_elems is output only parameter. This reflects the number of elements * in response buffer. The caller of this function to use *num_elems while * parsing the response buffer. */ static int ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf, u16 buf_size, u16 *req_desc, u16 *num_elems, struct ice_sq_cd *cd) { … } /** * ice_aq_add_vsi * @hw: pointer to the HW struct * @vsi_ctx: pointer to a VSI context struct * @cd: pointer to command details structure or NULL * * Add a VSI context to the hardware (0x0210) */ static int ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, struct ice_sq_cd *cd) { … } /** * ice_aq_free_vsi * @hw: pointer to the HW struct * @vsi_ctx: pointer to a VSI context struct * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources * @cd: pointer to command details structure or NULL * * Free VSI context info from hardware (0x0213) */ static int ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, bool keep_vsi_alloc, struct ice_sq_cd *cd) { … } /** * ice_aq_update_vsi * @hw: pointer to the HW struct * @vsi_ctx: pointer to a VSI context struct * @cd: pointer to command details structure or NULL * * Update VSI context in the hardware (0x0211) */ static int ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, struct ice_sq_cd *cd) { … } /** * ice_is_vsi_valid - check whether the VSI is valid or not * @hw: pointer to the HW struct * @vsi_handle: VSI handle * * check whether the VSI is valid or not */ bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_get_hw_vsi_num - return the HW VSI number * @hw: pointer to the HW struct * @vsi_handle: VSI handle * * return the HW VSI number * Caution: call this function only if VSI is valid (ice_is_vsi_valid) */ u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle * @hw: pointer to the HW struct * @vsi_handle: VSI handle * * return the VSI context entry for a given VSI handle */ struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_save_vsi_ctx - save the VSI context for a given VSI handle * @hw: pointer to the HW struct * @vsi_handle: VSI handle * @vsi: VSI context pointer * * save the VSI context entry for a given VSI handle */ static void ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) { … } /** * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs * @hw: pointer to the HW struct * @vsi_handle: VSI handle */ static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_clear_vsi_ctx - clear the VSI context entry * @hw: pointer to the HW struct * @vsi_handle: VSI handle * * clear the VSI context entry */ static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_clear_all_vsi_ctx - clear all the VSI context entries * @hw: pointer to the HW struct */ void ice_clear_all_vsi_ctx(struct ice_hw *hw) { … } /** * ice_add_vsi - add VSI context to the hardware and VSI handle list * @hw: pointer to the HW struct * @vsi_handle: unique VSI handle provided by drivers * @vsi_ctx: pointer to a VSI context struct * @cd: pointer to command details structure or NULL * * Add a VSI context to the hardware also add it into the VSI handle list. * If this function gets called after reset for existing VSIs then update * with the new HW VSI number in the corresponding VSI handle list entry. */ int ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, struct ice_sq_cd *cd) { … } /** * ice_free_vsi- free VSI context from hardware and VSI handle list * @hw: pointer to the HW struct * @vsi_handle: unique VSI handle * @vsi_ctx: pointer to a VSI context struct * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources * @cd: pointer to command details structure or NULL * * Free VSI context info from hardware as well as from VSI handle list */ int ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, bool keep_vsi_alloc, struct ice_sq_cd *cd) { … } /** * ice_update_vsi * @hw: pointer to the HW struct * @vsi_handle: unique VSI handle * @vsi_ctx: pointer to a VSI context struct * @cd: pointer to command details structure or NULL * * Update VSI context in the hardware */ int ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, struct ice_sq_cd *cd) { … } /** * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI * @hw: pointer to HW struct * @vsi_handle: VSI SW index * @enable: boolean for enable/disable */ int ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable) { … } /** * ice_aq_alloc_free_vsi_list * @hw: pointer to the HW struct * @vsi_list_id: VSI list ID returned or used for lookup * @lkup_type: switch rule filter lookup type * @opc: switch rules population command type - pass in the command opcode * * allocates or free a VSI list resource */ static int ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type, enum ice_adminq_opc opc) { … } /** * ice_aq_sw_rules - add/update/remove switch rules * @hw: pointer to the HW struct * @rule_list: pointer to switch rule population list * @rule_list_sz: total size of the rule list in bytes * @num_rules: number of switch rules in the rule_list * @opc: switch rules population command type - pass in the command opcode * @cd: pointer to command details structure or NULL * * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware */ int ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) { … } /** * ice_aq_add_recipe - add switch recipe * @hw: pointer to the HW struct * @s_recipe_list: pointer to switch rule population list * @num_recipes: number of switch recipes in the list * @cd: pointer to command details structure or NULL * * Add(0x0290) */ int ice_aq_add_recipe(struct ice_hw *hw, struct ice_aqc_recipe_data_elem *s_recipe_list, u16 num_recipes, struct ice_sq_cd *cd) { … } /** * ice_aq_get_recipe - get switch recipe * @hw: pointer to the HW struct * @s_recipe_list: pointer to switch rule population list * @num_recipes: pointer to the number of recipes (input and output) * @recipe_root: root recipe number of recipe(s) to retrieve * @cd: pointer to command details structure or NULL * * Get(0x0292) * * On input, *num_recipes should equal the number of entries in s_recipe_list. * On output, *num_recipes will equal the number of entries returned in * s_recipe_list. * * The caller must supply enough space in s_recipe_list to hold all possible * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES. */ int ice_aq_get_recipe(struct ice_hw *hw, struct ice_aqc_recipe_data_elem *s_recipe_list, u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd) { … } /** * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx * @hw: pointer to the HW struct * @params: parameters used to update the default recipe * * This function only supports updating default recipes and it only supports * updating a single recipe based on the lkup_idx at a time. * * This is done as a read-modify-write operation. First, get the current recipe * contents based on the recipe's ID. Then modify the field vector index and * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update * the pre-existing recipe with the modifications. */ int ice_update_recipe_lkup_idx(struct ice_hw *hw, struct ice_update_recipe_lkup_idx_params *params) { … } /** * ice_aq_map_recipe_to_profile - Map recipe to packet profile * @hw: pointer to the HW struct * @profile_id: package profile ID to associate the recipe with * @r_assoc: Recipe bitmap filled in and need to be returned as response * @cd: pointer to command details structure or NULL * Recipe to profile association (0x0291) */ int ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc, struct ice_sq_cd *cd) { … } /** * ice_aq_get_recipe_to_profile - Map recipe to packet profile * @hw: pointer to the HW struct * @profile_id: package profile ID to associate the recipe with * @r_assoc: Recipe bitmap filled in and need to be returned as response * @cd: pointer to command details structure or NULL * Associate profile ID with given recipe (0x0293) */ int ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc, struct ice_sq_cd *cd) { … } /** * ice_init_chk_recipe_reuse_support - check if recipe reuse is supported * @hw: pointer to the hardware structure */ void ice_init_chk_recipe_reuse_support(struct ice_hw *hw) { … } /** * ice_alloc_recipe - add recipe resource * @hw: pointer to the hardware structure * @rid: recipe ID returned as response to AQ call */ int ice_alloc_recipe(struct ice_hw *hw, u16 *rid) { … } /** * ice_free_recipe_res - free recipe resource * @hw: pointer to the hardware structure * @rid: recipe ID to free * * Return: 0 on success, and others on error */ static int ice_free_recipe_res(struct ice_hw *hw, u16 rid) { … } /** * ice_release_recipe_res - disassociate and free recipe resource * @hw: pointer to the hardware structure * @recp: the recipe struct resource to unassociate and free * * Return: 0 on success, and others on error */ static int ice_release_recipe_res(struct ice_hw *hw, struct ice_sw_recipe *recp) { … } /** * ice_get_recp_to_prof_map - updates recipe to profile mapping * @hw: pointer to hardware structure * * This function is used to populate recipe_to_profile matrix where index to * this array is the recipe ID and the element is the mapping of which profiles * is this recipe mapped to. */ static void ice_get_recp_to_prof_map(struct ice_hw *hw) { … } /** * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries * @hw: pointer to hardware structure * @recps: struct that we need to populate * @rid: recipe ID that we are populating * @refresh_required: true if we should get recipe to profile mapping from FW * @is_add: flag of adding recipe * * This function is used to populate all the necessary entries into our * bookkeeping so that we have a current list of all the recipes that are * programmed in the firmware. */ static int ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, bool *refresh_required, bool is_add) { … } /* ice_init_port_info - Initialize port_info with switch configuration data * @pi: pointer to port_info * @vsi_port_num: VSI number or port number * @type: Type of switch element (port or VSI) * @swid: switch ID of the switch the element is attached to * @pf_vf_num: PF or VF number * @is_vf: true if the element is a VF, false otherwise */ static void ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, u16 swid, u16 pf_vf_num, bool is_vf) { … } /* ice_get_initial_sw_cfg - Get initial port and default VSI data * @hw: pointer to the hardware structure */ int ice_get_initial_sw_cfg(struct ice_hw *hw) { … } /** * ice_fill_sw_info - Helper function to populate lb_en and lan_en * @hw: pointer to the hardware structure * @fi: filter info structure to fill/update * * This helper function populates the lb_en and lan_en elements of the provided * ice_fltr_info struct using the switch's type and characteristics of the * switch rule being configured. */ static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi) { … } /** * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer * @eth_hdr: pointer to buffer to populate */ void ice_fill_eth_hdr(u8 *eth_hdr) { … } /** * ice_fill_sw_rule - Helper function to fill switch rule structure * @hw: pointer to the hardware structure * @f_info: entry containing packet forwarding information * @s_rule: switch rule structure to be filled in based on mac_entry * @opc: switch rules population command type - pass in the command opcode */ static void ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, struct ice_sw_rule_lkup_rx_tx *s_rule, enum ice_adminq_opc opc) { … } /** * ice_add_marker_act * @hw: pointer to the hardware structure * @m_ent: the management entry for which sw marker needs to be added * @sw_marker: sw marker to tag the Rx descriptor with * @l_id: large action resource ID * * Create a large action to hold software marker and update the switch rule * entry pointed by m_ent with newly created large action */ static int ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, u16 sw_marker, u16 l_id) { … } /** * ice_create_vsi_list_map * @hw: pointer to the hardware structure * @vsi_handle_arr: array of VSI handles to set in the VSI mapping * @num_vsi: number of VSI handles in the array * @vsi_list_id: VSI list ID generated as part of allocate resource * * Helper function to create a new entry of VSI list ID to VSI mapping * using the given VSI list ID */ static struct ice_vsi_list_map_info * ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, u16 vsi_list_id) { … } /** * ice_update_vsi_list_rule * @hw: pointer to the hardware structure * @vsi_handle_arr: array of VSI handles to form a VSI list * @num_vsi: number of VSI handles in the array * @vsi_list_id: VSI list ID generated as part of allocate resource * @remove: Boolean value to indicate if this is a remove action * @opc: switch rules population command type - pass in the command opcode * @lkup_type: lookup type of the filter * * Call AQ command to add a new switch rule or update existing switch rule * using the given VSI list ID */ static int ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, enum ice_sw_lkup_type lkup_type) { … } /** * ice_create_vsi_list_rule - Creates and populates a VSI list rule * @hw: pointer to the HW struct * @vsi_handle_arr: array of VSI handles to form a VSI list * @num_vsi: number of VSI handles in the array * @vsi_list_id: stores the ID of the VSI list to be created * @lkup_type: switch rule filter's lookup type */ static int ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) { … } /** * ice_create_pkt_fwd_rule * @hw: pointer to the hardware structure * @f_entry: entry containing packet forwarding information * * Create switch rule with given filter information and add an entry * to the corresponding filter management list to track this switch rule * and VSI mapping */ static int ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) { … } /** * ice_update_pkt_fwd_rule * @hw: pointer to the hardware structure * @f_info: filter information for switch rule * * Call AQ command to update a previously created switch rule with a * VSI list ID */ static int ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) { … } /** * ice_update_sw_rule_bridge_mode * @hw: pointer to the HW struct * * Updates unicast switch filter rules based on VEB/VEPA mode */ int ice_update_sw_rule_bridge_mode(struct ice_hw *hw) { … } /** * ice_add_update_vsi_list * @hw: pointer to the hardware structure * @m_entry: pointer to current filter management list entry * @cur_fltr: filter information from the book keeping entry * @new_fltr: filter information with the new VSI to be added * * Call AQ command to add or update previously created VSI list with new VSI. * * Helper function to do book keeping associated with adding filter information * The algorithm to do the book keeping is described below : * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.) * if only one VSI has been added till now * Allocate a new VSI list and add two VSIs * to this list using switch rule command * Update the previously created switch rule with the * newly created VSI list ID * if a VSI list was previously created * Add the new VSI to the previously created VSI list set * using the update switch rule command */ static int ice_add_update_vsi_list(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_entry, struct ice_fltr_info *cur_fltr, struct ice_fltr_info *new_fltr) { … } /** * ice_find_rule_entry - Search a rule entry * @hw: pointer to the hardware structure * @recp_id: lookup type for which the specified rule needs to be searched * @f_info: rule information * * Helper function to search for a given rule entry * Returns pointer to entry storing the rule if found */ static struct ice_fltr_mgmt_list_entry * ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info) { … } /** * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 * @hw: pointer to the hardware structure * @recp_id: lookup type for which VSI lists needs to be searched * @vsi_handle: VSI handle to be found in VSI list * @vsi_list_id: VSI list ID found containing vsi_handle * * Helper function to search a VSI list with single entry containing given VSI * handle element. This can be extended further to search VSI list with more * than 1 vsi_count. Returns pointer to VSI list entry if found. */ struct ice_vsi_list_map_info * ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle, u16 *vsi_list_id) { … } /** * ice_add_rule_internal - add rule for a given lookup type * @hw: pointer to the hardware structure * @recp_id: lookup type (recipe ID) for which rule has to be added * @f_entry: structure containing MAC forwarding information * * Adds or updates the rule lists for a given recipe */ static int ice_add_rule_internal(struct ice_hw *hw, u8 recp_id, struct ice_fltr_list_entry *f_entry) { … } /** * ice_remove_vsi_list_rule * @hw: pointer to the hardware structure * @vsi_list_id: VSI list ID generated as part of allocate resource * @lkup_type: switch rule filter lookup type * * The VSI list should be emptied before this function is called to remove the * VSI list. */ static int ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, enum ice_sw_lkup_type lkup_type) { … } /** * ice_rem_update_vsi_list * @hw: pointer to the hardware structure * @vsi_handle: VSI handle of the VSI to remove * @fm_list: filter management entry for which the VSI list management needs to * be done */ static int ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, struct ice_fltr_mgmt_list_entry *fm_list) { … } /** * ice_remove_rule_internal - Remove a filter rule of a given type * @hw: pointer to the hardware structure * @recp_id: recipe ID for which the rule needs to removed * @f_entry: rule entry containing filter information */ static int ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id, struct ice_fltr_list_entry *f_entry) { … } /** * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI * @hw: pointer to the hardware structure * @vlan_id: VLAN ID * @vsi_handle: check MAC filter for this VSI */ bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle) { … } /** * ice_add_mac - Add a MAC address based filter rule * @hw: pointer to the hardware structure * @m_list: list of MAC addresses and forwarding information */ int ice_add_mac(struct ice_hw *hw, struct list_head *m_list) { … } /** * ice_add_vlan_internal - Add one VLAN based filter rule * @hw: pointer to the hardware structure * @f_entry: filter entry containing one VLAN information */ static int ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) { … } /** * ice_add_vlan - Add VLAN based filter rule * @hw: pointer to the hardware structure * @v_list: list of VLAN entries and forwarding information */ int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list) { … } /** * ice_add_eth_mac - Add ethertype and MAC based filter rule * @hw: pointer to the hardware structure * @em_list: list of ether type MAC filter, MAC is optional * * This function requires the caller to populate the entries in * the filter list with the necessary fields (including flags to * indicate Tx or Rx rules). */ int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list) { … } /** * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule * @hw: pointer to the hardware structure * @em_list: list of ethertype or ethertype MAC entries */ int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list) { … } /** * ice_rem_sw_rule_info * @hw: pointer to the hardware structure * @rule_head: pointer to the switch list structure that we want to delete */ static void ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head) { … } /** * ice_rem_adv_rule_info * @hw: pointer to the hardware structure * @rule_head: pointer to the switch list structure that we want to delete */ static void ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head) { … } /** * ice_cfg_dflt_vsi - change state of VSI to set/clear default * @pi: pointer to the port_info structure * @vsi_handle: VSI handle to set as default * @set: true to add the above mentioned switch rule, false to remove it * @direction: ICE_FLTR_RX or ICE_FLTR_TX * * add filter rule to set/unset given VSI as default VSI for the switch * (represented by swid) */ int ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, u8 direction) { … } /** * ice_vsi_uses_fltr - Determine if given VSI uses specified filter * @fm_entry: filter entry to inspect * @vsi_handle: VSI handle to compare with filter info */ static bool ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) { … } /** * ice_check_if_dflt_vsi - check if VSI is default VSI * @pi: pointer to the port_info structure * @vsi_handle: vsi handle to check for in filter list * @rule_exists: indicates if there are any VSI's in the rule list * * checks if the VSI is in a default VSI list, and also indicates * if the default VSI list is empty */ bool ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool *rule_exists) { … } /** * ice_remove_mac - remove a MAC address based filter rule * @hw: pointer to the hardware structure * @m_list: list of MAC addresses and forwarding information * * This function removes either a MAC filter rule or a specific VSI from a * VSI list for a multicast MAC address. * * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should * be aware that this call will only work if all the entries passed into m_list * were added previously. It will not attempt to do a partial remove of entries * that were found. */ int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) { … } /** * ice_remove_vlan - Remove VLAN based filter rule * @hw: pointer to the hardware structure * @v_list: list of VLAN entries and forwarding information */ int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list) { … } /** * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to remove filters from * @vsi_list_head: pointer to the list to add entry to * @fi: pointer to fltr_info of filter entry to copy & add * * Helper function, used when creating a list of filters to remove from * a specific VSI. The entry added to vsi_list_head is a COPY of the * original filter entry, with the exception of fltr_info.fltr_act and * fltr_info.fwd_id fields. These are set such that later logic can * extract which VSI to remove the fltr from, and pass on that information. */ static int ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, struct list_head *vsi_list_head, struct ice_fltr_info *fi) { … } /** * ice_add_to_vsi_fltr_list - Add VSI filters to the list * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to remove filters from * @lkup_list_head: pointer to the list that has certain lookup type filters * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle * * Locates all filters in lkup_list_head that are used by the given VSI, * and adds COPIES of those entries to vsi_list_head (intended to be used * to remove the listed filters). * Note that this means all entries in vsi_list_head must be explicitly * deallocated by the caller when done with list. */ static int ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, struct list_head *lkup_list_head, struct list_head *vsi_list_head) { … } /** * ice_determine_promisc_mask * @fi: filter info to parse * * Helper function to determine which ICE_PROMISC_ mask corresponds * to given filter into. */ static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi) { … } /** * ice_remove_promisc - Remove promisc based filter rules * @hw: pointer to the hardware structure * @recp_id: recipe ID for which the rule needs to removed * @v_list: list of promisc entries */ static int ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list) { … } /** * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to clear mode * @promisc_mask: mask of promiscuous config bits to clear * @vid: VLAN ID to clear VLAN promiscuous */ int ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid) { … } /** * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to configure * @promisc_mask: mask of promiscuous config bits * @vid: VLAN ID to set VLAN promiscuous */ int ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid) { … } /** * ice_set_vlan_vsi_promisc * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to configure * @promisc_mask: mask of promiscuous config bits * @rm_vlan_promisc: Clear VLANs VSI promisc mode * * Configure VSI with all associated VLANs to given promiscuous mode(s) */ int ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, bool rm_vlan_promisc) { … } /** * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to remove filters from * @lkup: switch rule filter lookup type */ static void ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, enum ice_sw_lkup_type lkup) { … } /** * ice_remove_vsi_fltr - Remove all filters for a VSI * @hw: pointer to the hardware structure * @vsi_handle: VSI handle to remove filters from */ void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_alloc_res_cntr - allocating resource counter * @hw: pointer to the hardware structure * @type: type of resource * @alloc_shared: if set it is shared else dedicated * @num_items: number of entries requested for FD resource type * @counter_id: counter index returned by AQ call */ int ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, u16 *counter_id) { … } /** * ice_free_res_cntr - free resource counter * @hw: pointer to the hardware structure * @type: type of resource * @alloc_shared: if set it is shared else dedicated * @num_items: number of entries to be freed for FD resource type * @counter_id: counter ID resource which needs to be freed */ int ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, u16 counter_id) { … } #define ICE_PROTOCOL_ENTRY(id, ...) … /** * ice_share_res - set a resource as shared or dedicated * @hw: hw struct of original owner of resource * @type: resource type * @shared: is the resource being set to shared * @res_id: resource id (descriptor) */ int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id) { … } /* This is mapping table entry that maps every word within a given protocol * structure to the real byte offset as per the specification of that * protocol header. * for example dst address is 3 words in ethertype header and corresponding * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a * matching entry describing its field. This needs to be updated if new * structure is added to that union. */ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = …; static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = …; /** * ice_find_recp - find a recipe * @hw: pointer to the hardware structure * @lkup_exts: extension sequence to match * @rinfo: information regarding the rule e.g. priority and action info * @is_add: flag of adding recipe * * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. */ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, const struct ice_adv_rule_info *rinfo, bool is_add) { … } /** * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl * * As protocol id for outer vlan is different in dvm and svm, if dvm is * supported protocol array record for outer vlan has to be modified to * reflect the value proper for DVM. */ void ice_change_proto_id_to_dvm(void) { … } /** * ice_prot_type_to_id - get protocol ID from protocol type * @type: protocol type * @id: pointer to variable that will receive the ID * * Returns true if found, false otherwise */ static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) { … } /** * ice_fill_valid_words - count valid words * @rule: advanced rule with lookup information * @lkup_exts: byte offset extractions of the words that are valid * * calculate valid words in a lookup rule using mask value */ static u8 ice_fill_valid_words(struct ice_adv_lkup_elem *rule, struct ice_prot_lkup_ext *lkup_exts) { … } /** * ice_fill_fv_word_index - fill in the field vector indices for a recipe group * @hw: pointer to the hardware structure * @rm: recipe management list entry * * Helper function to fill in the field vector indices for protocol-offset * pairs. These indexes are then ultimately programmed into a recipe. */ static int ice_fill_fv_word_index(struct ice_hw *hw, struct ice_sw_recipe *rm) { … } /** * ice_find_free_recp_res_idx - find free result indexes for recipe * @hw: pointer to hardware structure * @profiles: bitmap of profiles that will be associated with the new recipe * @free_idx: pointer to variable to receive the free index bitmap * * The algorithm used here is: * 1. When creating a new recipe, create a set P which contains all * Profiles that will be associated with our new recipe * * 2. For each Profile p in set P: * a. Add all recipes associated with Profile p into set R * b. Optional : PossibleIndexes &= profile[p].possibleIndexes * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] * i. Or just assume they all have the same possible indexes: * 44, 45, 46, 47 * i.e., PossibleIndexes = 0x0000F00000000000 * * 3. For each Recipe r in set R: * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes * b. FreeIndexes = UsedIndexes ^ PossibleIndexes * * FreeIndexes will contain the bits indicating the indexes free for use, * then the code needs to update the recipe[r].used_result_idx_bits to * indicate which indexes were selected for use by this recipe. */ static u16 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, unsigned long *free_idx) { … } /** * ice_calc_recp_cnt - calculate number of recipes based on word count * @word_cnt: number of lookup words * * Word count should include switch ID word and regular lookup words. * Returns: number of recipes required to fit @word_cnt, including extra recipes * needed for recipe chaining (if needed). */ static int ice_calc_recp_cnt(u8 word_cnt) { … } static void fill_recipe_template(struct ice_aqc_recipe_data_elem *recp, u16 rid, const struct ice_sw_recipe *rm) { … } static void bookkeep_recipe(struct ice_sw_recipe *recipe, struct ice_aqc_recipe_data_elem *r, const struct ice_sw_recipe *rm) { … } /* For memcpy in ice_add_sw_recipe. */ static_assert(…); /** * ice_add_sw_recipe - function to call AQ calls to create switch recipe * @hw: pointer to hardware structure * @rm: recipe management list entry * @profiles: bitmap of profiles that will be associated. */ static int ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, unsigned long *profiles) { … } /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule * @hw: pointer to hardware structure * @rinfo: other information regarding the rule e.g. priority and action info * @bm: pointer to memory for returning the bitmap of field vectors */ static void ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, unsigned long *bm) { … } /** * ice_subscribe_recipe - subscribe to an existing recipe * @hw: pointer to the hardware structure * @rid: recipe ID to subscribe to * * Return: 0 on success, and others on error */ static int ice_subscribe_recipe(struct ice_hw *hw, u16 rid) { … } /** * ice_subscribable_recp_shared - share an existing subscribable recipe * @hw: pointer to the hardware structure * @rid: recipe ID to subscribe to */ static void ice_subscribable_recp_shared(struct ice_hw *hw, u16 rid) { … } /** * ice_add_adv_recipe - Add an advanced recipe that is not part of the default * @hw: pointer to hardware structure * @lkups: lookup elements or match criteria for the advanced recipe, one * structure per protocol header * @lkups_cnt: number of protocols * @rinfo: other information regarding the rule e.g. priority and action info * @rid: return the recipe ID of the recipe created */ static int ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) { … } /** * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt * * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added * @num_vlan: number of VLAN tags */ static struct ice_dummy_pkt_profile * ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, u32 num_vlan) { … } /** * ice_find_dummy_packet - find dummy packet * * @lkups: lookup elements or match criteria for the advanced recipe, one * structure per protocol header * @lkups_cnt: number of protocols * @tun_type: tunnel type * * Returns the &ice_dummy_pkt_profile corresponding to these lookup params. */ static const struct ice_dummy_pkt_profile * ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, enum ice_sw_tunnel_type tun_type) { … } /** * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria * * @lkups: lookup elements or match criteria for the advanced recipe, one * structure per protocol header * @lkups_cnt: number of protocols * @s_rule: stores rule information from the match criteria * @profile: dummy packet profile (the template, its size and header offsets) */ static int ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, struct ice_sw_rule_lkup_rx_tx *s_rule, const struct ice_dummy_pkt_profile *profile) { … } /** * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port * @hw: pointer to the hardware structure * @tun_type: tunnel type * @pkt: dummy packet to fill in * @offsets: offset info for the dummy packet */ static int ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) { … } /** * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type * @hw: pointer to hw structure * @vlan_type: VLAN tag type * @pkt: dummy packet to fill in * @offsets: offset info for the dummy packet */ static int ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) { … } static bool ice_rules_equal(const struct ice_adv_rule_info *first, const struct ice_adv_rule_info *second) { … } /** * ice_find_adv_rule_entry - Search a rule entry * @hw: pointer to the hardware structure * @lkups: lookup elements or match criteria for the advanced recipe, one * structure per protocol header * @lkups_cnt: number of protocols * @recp_id: recipe ID for which we are finding the rule * @rinfo: other information regarding the rule e.g. priority and action info * * Helper function to search for a given advance rule entry * Returns pointer to entry storing the rule if found */ static struct ice_adv_fltr_mgmt_list_entry * ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, u16 recp_id, struct ice_adv_rule_info *rinfo) { … } /** * ice_adv_add_update_vsi_list * @hw: pointer to the hardware structure * @m_entry: pointer to current adv filter management list entry * @cur_fltr: filter information from the book keeping entry * @new_fltr: filter information with the new VSI to be added * * Call AQ command to add or update previously created VSI list with new VSI. * * Helper function to do book keeping associated with adding filter information * The algorithm to do the booking keeping is described below : * When a VSI needs to subscribe to a given advanced filter * if only one VSI has been added till now * Allocate a new VSI list and add two VSIs * to this list using switch rule command * Update the previously created switch rule with the * newly created VSI list ID * if a VSI list was previously created * Add the new VSI to the previously created VSI list set * using the update switch rule command */ static int ice_adv_add_update_vsi_list(struct ice_hw *hw, struct ice_adv_fltr_mgmt_list_entry *m_entry, struct ice_adv_rule_info *cur_fltr, struct ice_adv_rule_info *new_fltr) { … } void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup) { … } void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup) { … } void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup) { … } void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup) { … } /** * ice_add_adv_rule - helper function to create an advanced switch rule * @hw: pointer to the hardware structure * @lkups: information on the words that needs to be looked up. All words * together makes one recipe * @lkups_cnt: num of entries in the lkups array * @rinfo: other information related to the rule that needs to be programmed * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be * ignored is case of error. * * This function can program only 1 rule at a time. The lkups is used to * describe the all the words that forms the "lookup" portion of the recipe. * These words can span multiple protocols. Callers to this function need to * pass in a list of protocol headers with lookup information along and mask * that determines which words are valid from the given protocol header. * rinfo describes other information related to this rule such as forwarding * IDs, priority of this rule, etc. */ int ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, struct ice_adv_rule_info *rinfo, struct ice_rule_query_data *added_entry) { … } /** * ice_replay_vsi_fltr - Replay filters for requested VSI * @hw: pointer to the hardware structure * @vsi_handle: driver VSI handle * @recp_id: Recipe ID for which rules need to be replayed * @list_head: list for which filters need to be replayed * * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. * It is required to pass valid VSI handle. */ static int ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, struct list_head *list_head) { … } /** * ice_adv_rem_update_vsi_list * @hw: pointer to the hardware structure * @vsi_handle: VSI handle of the VSI to remove * @fm_list: filter management entry for which the VSI list management needs to * be done */ static int ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, struct ice_adv_fltr_mgmt_list_entry *fm_list) { … } /** * ice_rem_adv_rule - removes existing advanced switch rule * @hw: pointer to the hardware structure * @lkups: information on the words that needs to be looked up. All words * together makes one recipe * @lkups_cnt: num of entries in the lkups array * @rinfo: Its the pointer to the rule information for the rule * * This function can be used to remove 1 rule at a time. The lkups is * used to describe all the words that forms the "lookup" portion of the * rule. These words can span multiple protocols. Callers to this function * need to pass in a list of protocol headers with lookup information along * and mask that determines which words are valid from the given protocol * header. rinfo describes other information related to this rule such as * forwarding IDs, priority of this rule, etc. */ static int ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, struct ice_adv_rule_info *rinfo) { … } /** * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID * @hw: pointer to the hardware structure * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID * * This function is used to remove 1 rule at a time. The removal is based on * the remove_entry parameter. This function will remove rule for a given * vsi_handle with a given rule_id which is passed as parameter in remove_entry */ int ice_rem_adv_rule_by_id(struct ice_hw *hw, struct ice_rule_query_data *remove_entry) { … } /** * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI * @hw: pointer to the hardware structure * @vsi_handle: driver VSI handle * @list_head: list for which filters need to be replayed * * Replay the advanced rule for the given VSI. */ static int ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, struct list_head *list_head) { … } /** * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists * @hw: pointer to the hardware structure * @vsi_handle: driver VSI handle * * Replays filters for requested VSI via vsi_handle. */ int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) { … } /** * ice_rm_all_sw_replay_rule_info - deletes filter replay rules * @hw: pointer to the HW struct * * Deletes the filter replay rules. */ void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) { … }