// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2022, Intel Corporation. */ #include "ice_vf_lib_private.h" #include "ice.h" #include "ice_lib.h" #include "ice_fltr.h" #include "ice_virtchnl_allowlist.h" /* Public functions which may be accessed by all driver files */ /** * ice_get_vf_by_id - Get pointer to VF by ID * @pf: the PF private structure * @vf_id: the VF ID to locate * * Locate and return a pointer to the VF structure associated with a given ID. * Returns NULL if the ID does not have a valid VF structure associated with * it. * * This function takes a reference to the VF, which must be released by * calling ice_put_vf() once the caller is finished accessing the VF structure * returned. */ struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id) { … } /** * ice_release_vf - Release VF associated with a refcount * @ref: the kref decremented to zero * * Callback function for kref_put to release a VF once its reference count has * hit zero. */ static void ice_release_vf(struct kref *ref) { … } /** * ice_put_vf - Release a reference to a VF * @vf: the VF structure to decrease reference count on * * Decrease the reference count for a VF, and free the entry if it is no * longer in use. * * This must be called after ice_get_vf_by_id() once the reference to the VF * structure is no longer used. Otherwise, the VF structure will never be * freed. */ void ice_put_vf(struct ice_vf *vf) { … } /** * ice_has_vfs - Return true if the PF has any associated VFs * @pf: the PF private structure * * Return whether or not the PF has any allocated VFs. * * Note that this function only guarantees that there are no VFs at the point * of calling it. It does not guarantee that no more VFs will be added. */ bool ice_has_vfs(struct ice_pf *pf) { … } /** * ice_get_num_vfs - Get number of allocated VFs * @pf: the PF private structure * * Return the total number of allocated VFs. NOTE: VF IDs are not guaranteed * to be contiguous. Do not assume that a VF ID is guaranteed to be less than * the output of this function. */ u16 ice_get_num_vfs(struct ice_pf *pf) { … } /** * ice_get_vf_vsi - get VF's VSI based on the stored index * @vf: VF used to get VSI */ struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf) { … } /** * ice_is_vf_disabled * @vf: pointer to the VF info * * If the PF has been disabled, there is no need resetting VF until PF is * active again. Similarly, if the VF has been disabled, this means something * else is resetting the VF, so we shouldn't continue. * * Returns true if the caller should consider the VF as disabled whether * because that single VF is explicitly disabled or because the PF is * currently disabled. */ bool ice_is_vf_disabled(struct ice_vf *vf) { … } /** * ice_wait_on_vf_reset - poll to make sure a given VF is ready after reset * @vf: The VF being resseting * * The max poll time is about ~800ms, which is about the maximum time it takes * for a VF to be reset and/or a VF driver to be removed. */ static void ice_wait_on_vf_reset(struct ice_vf *vf) { … } /** * ice_check_vf_ready_for_cfg - check if VF is ready to be configured/queried * @vf: VF to check if it's ready to be configured/queried * * The purpose of this function is to make sure the VF is not in reset, not * disabled, and initialized so it can be configured and/or queried by a host * administrator. */ int ice_check_vf_ready_for_cfg(struct ice_vf *vf) { … } /** * ice_trigger_vf_reset - Reset a VF on HW * @vf: pointer to the VF structure * @is_vflr: true if VFLR was issued, false if not * @is_pfr: true if the reset was triggered due to a previous PFR * * Trigger hardware to start a reset for a particular VF. Expects the caller * to wait the proper amount of time to allow hardware to reset the VF before * it cleans up and restores VF functionality. */ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr) { … } static void ice_vf_clear_counters(struct ice_vf *vf) { … } /** * ice_vf_pre_vsi_rebuild - tasks to be done prior to VSI rebuild * @vf: VF to perform pre VSI rebuild tasks * * These tasks are items that don't need to be amortized since they are most * likely called in a for loop with all VF(s) in the reset_all_vfs() case. */ static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf) { … } /** * ice_vf_reconfig_vsi - Reconfigure a VF VSI with the device * @vf: VF to reconfigure the VSI for * * This is called when a single VF is being reset (i.e. VVF, VFLR, host VF * configuration change, etc). * * It brings the VSI down and then reconfigures it with the hardware. */ static int ice_vf_reconfig_vsi(struct ice_vf *vf) { … } /** * ice_vf_rebuild_vsi - rebuild the VF's VSI * @vf: VF to rebuild the VSI for * * This is only called when all VF(s) are being reset (i.e. PCIe Reset on the * host, PFR, CORER, etc.). * * It reprograms the VSI configuration back into hardware. */ static int ice_vf_rebuild_vsi(struct ice_vf *vf) { … } /** * ice_vf_rebuild_host_vlan_cfg - add VLAN 0 filter or rebuild the Port VLAN * @vf: VF to add MAC filters for * @vsi: Pointer to VSI * * Called after a VF VSI has been re-added/rebuilt during reset. The PF driver * always re-adds either a VLAN 0 or port VLAN based filter after reset. */ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf, struct ice_vsi *vsi) { … } /** * ice_vf_rebuild_host_tx_rate_cfg - re-apply the Tx rate limiting configuration * @vf: VF to re-apply the configuration for * * Called after a VF VSI has been re-added/rebuild during reset. The PF driver * needs to re-apply the host configured Tx rate limiting configuration. */ static int ice_vf_rebuild_host_tx_rate_cfg(struct ice_vf *vf) { … } /** * ice_vf_set_host_trust_cfg - set trust setting based on pre-reset value * @vf: VF to configure trust setting for */ static void ice_vf_set_host_trust_cfg(struct ice_vf *vf) { … } /** * ice_vf_rebuild_host_mac_cfg - add broadcast and the VF's perm_addr/LAA * @vf: VF to add MAC filters for * * Called after a VF VSI has been re-added/rebuilt during reset. The PF driver * always re-adds a broadcast filter and the VF's perm_addr/LAA after reset. */ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf) { … } /** * ice_vf_rebuild_aggregator_node_cfg - rebuild aggregator node config * @vsi: Pointer to VSI * * This function moves VSI into corresponding scheduler aggregator node * based on cached value of "aggregator node info" per VSI */ static void ice_vf_rebuild_aggregator_node_cfg(struct ice_vsi *vsi) { … } /** * ice_vf_rebuild_host_cfg - host admin configuration is persistent across reset * @vf: VF to rebuild host configuration on */ static void ice_vf_rebuild_host_cfg(struct ice_vf *vf) { … } /** * ice_set_vf_state_qs_dis - Set VF queues state to disabled * @vf: pointer to the VF structure */ static void ice_set_vf_state_qs_dis(struct ice_vf *vf) { … } /** * ice_vf_set_initialized - VF is ready for VIRTCHNL communication * @vf: VF to set in initialized state * * After this function the VF will be ready to receive/handle the * VIRTCHNL_OP_GET_VF_RESOURCES message */ static void ice_vf_set_initialized(struct ice_vf *vf) { … } /** * ice_vf_post_vsi_rebuild - Reset tasks that occur after VSI rebuild * @vf: the VF being reset * * Perform reset tasks which must occur after the VSI has been re-created or * rebuilt during a VF reset. */ static void ice_vf_post_vsi_rebuild(struct ice_vf *vf) { … } /** * ice_is_any_vf_in_unicast_promisc - check if any VF(s) * are in unicast promiscuous mode * @pf: PF structure for accessing VF(s) * * Return false if no VF(s) are in unicast promiscuous mode, * else return true */ bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf) { … } /** * ice_vf_get_promisc_masks - Calculate masks for promiscuous modes * @vf: the VF pointer * @vsi: the VSI to configure * @ucast_m: promiscuous mask to apply to unicast * @mcast_m: promiscuous mask to apply to multicast * * Decide which mask should be used for unicast and multicast filter, * based on presence of VLANs */ void ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi, u8 *ucast_m, u8 *mcast_m) { … } /** * ice_vf_clear_all_promisc_modes - Clear promisc/allmulticast on VF VSI * @vf: the VF pointer * @vsi: the VSI to configure * * Clear all promiscuous/allmulticast filters for a VF */ static int ice_vf_clear_all_promisc_modes(struct ice_vf *vf, struct ice_vsi *vsi) { … } /** * ice_vf_set_vsi_promisc - Enable promiscuous mode for a VF VSI * @vf: the VF to configure * @vsi: the VF's VSI * @promisc_m: the promiscuous mode to enable */ int ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m) { … } /** * ice_vf_clear_vsi_promisc - Disable promiscuous mode for a VF VSI * @vf: the VF to configure * @vsi: the VF's VSI * @promisc_m: the promiscuous mode to disable */ int ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m) { … } /** * ice_reset_all_vfs - reset all allocated VFs in one go * @pf: pointer to the PF structure * * Reset all VFs at once, in response to a PF or other device reset. * * First, tell the hardware to reset each VF, then do all the waiting in one * chunk, and finally finish restoring each VF after the wait. This is useful * during PF routines which need to reset all VFs, as otherwise it must perform * these resets in a serialized fashion. */ void ice_reset_all_vfs(struct ice_pf *pf) { … } /** * ice_notify_vf_reset - Notify VF of a reset event * @vf: pointer to the VF structure */ static void ice_notify_vf_reset(struct ice_vf *vf) { … } /** * ice_reset_vf - Reset a particular VF * @vf: pointer to the VF structure * @flags: flags controlling behavior of the reset * * Flags: * ICE_VF_RESET_VFLR - Indicates a reset is due to VFLR event * ICE_VF_RESET_NOTIFY - Send VF a notification prior to reset * ICE_VF_RESET_LOCK - Acquire VF cfg_lock before resetting * * Returns 0 if the VF is currently in reset, if resets are disabled, or if * the VF resets successfully. Returns an error code if the VF fails to * rebuild. */ int ice_reset_vf(struct ice_vf *vf, u32 flags) { … } /** * ice_set_vf_state_dis - Set VF state to disabled * @vf: pointer to the VF structure */ void ice_set_vf_state_dis(struct ice_vf *vf) { … } /* Private functions only accessed from other virtualization files */ /** * ice_initialize_vf_entry - Initialize a VF entry * @vf: pointer to the VF structure */ void ice_initialize_vf_entry(struct ice_vf *vf) { … } /** * ice_dis_vf_qs - Disable the VF queues * @vf: pointer to the VF structure */ void ice_dis_vf_qs(struct ice_vf *vf) { … } /** * ice_err_to_virt_err - translate errors for VF return code * @err: error return code */ enum virtchnl_status_code ice_err_to_virt_err(int err) { … } /** * ice_check_vf_init - helper to check if VF init complete * @vf: the pointer to the VF to check */ int ice_check_vf_init(struct ice_vf *vf) { … } /** * ice_vf_get_port_info - Get the VF's port info structure * @vf: VF used to get the port info structure for */ struct ice_port_info *ice_vf_get_port_info(struct ice_vf *vf) { … } /** * ice_cfg_mac_antispoof - Configure MAC antispoof checking behavior * @vsi: the VSI to configure * @enable: whether to enable or disable the spoof checking * * Configure a VSI to enable (or disable) spoof checking behavior. */ static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable) { … } /** * ice_vsi_ena_spoofchk - enable Tx spoof checking for this VSI * @vsi: VSI to enable Tx spoof checking for */ static int ice_vsi_ena_spoofchk(struct ice_vsi *vsi) { … } /** * ice_vsi_dis_spoofchk - disable Tx spoof checking for this VSI * @vsi: VSI to disable Tx spoof checking for */ static int ice_vsi_dis_spoofchk(struct ice_vsi *vsi) { … } /** * ice_vsi_apply_spoofchk - Apply Tx spoof checking setting to a VSI * @vsi: VSI associated to the VF * @enable: whether to enable or disable the spoof checking */ int ice_vsi_apply_spoofchk(struct ice_vsi *vsi, bool enable) { … } /** * ice_is_vf_trusted * @vf: pointer to the VF info */ bool ice_is_vf_trusted(struct ice_vf *vf) { … } /** * ice_vf_has_no_qs_ena - check if the VF has any Rx or Tx queues enabled * @vf: the VF to check * * Returns true if the VF has no Rx and no Tx queues enabled and returns false * otherwise */ bool ice_vf_has_no_qs_ena(struct ice_vf *vf) { … } /** * ice_is_vf_link_up - check if the VF's link is up * @vf: VF to check if link is up */ bool ice_is_vf_link_up(struct ice_vf *vf) { … } /** * ice_vf_ctrl_invalidate_vsi - invalidate ctrl_vsi_idx to remove VSI access * @vf: VF that control VSI is being invalidated on */ void ice_vf_ctrl_invalidate_vsi(struct ice_vf *vf) { … } /** * ice_vf_ctrl_vsi_release - invalidate the VF's control VSI after freeing it * @vf: VF that control VSI is being released on */ void ice_vf_ctrl_vsi_release(struct ice_vf *vf) { … } /** * ice_vf_ctrl_vsi_setup - Set up a VF control VSI * @vf: VF to setup control VSI for * * Returns pointer to the successfully allocated VSI struct on success, * otherwise returns NULL on failure. */ struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf) { … } /** * ice_vf_init_host_cfg - Initialize host admin configuration * @vf: VF to initialize * @vsi: the VSI created at initialization * * Initialize the VF host configuration. Called during VF creation to setup * VLAN 0, add the VF VSI broadcast filter, and setup spoof checking. It * should only be called during VF creation. */ int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi) { … } /** * ice_vf_invalidate_vsi - invalidate vsi_idx to remove VSI access * @vf: VF to remove access to VSI for */ void ice_vf_invalidate_vsi(struct ice_vf *vf) { … } /** * ice_vf_vsi_release - Release the VF VSI and invalidate indexes * @vf: pointer to the VF structure * * Release the VF associated with this VSI and then invalidate the VSI * indexes. */ void ice_vf_vsi_release(struct ice_vf *vf) { … } /** * ice_get_vf_ctrl_vsi - Get first VF control VSI pointer * @pf: the PF private structure * @vsi: pointer to the VSI * * Return first found VF control VSI other than the vsi * passed by parameter. This function is used to determine * whether new resources have to be allocated for control VSI * or they can be shared with existing one. * * Return found VF control VSI pointer other itself. Return * NULL Otherwise. * */ struct ice_vsi *ice_get_vf_ctrl_vsi(struct ice_pf *pf, struct ice_vsi *vsi) { … }