10deb0bf7SJacob Keller // SPDX-License-Identifier: GPL-2.0 20deb0bf7SJacob Keller /* Copyright (c) 2018, Intel Corporation. */ 30deb0bf7SJacob Keller 40deb0bf7SJacob Keller #include "ice.h" 5109aba47SJacob Keller #include "ice_vf_lib_private.h" 60deb0bf7SJacob Keller #include "ice_base.h" 70deb0bf7SJacob Keller #include "ice_lib.h" 80deb0bf7SJacob Keller #include "ice_fltr.h" 90deb0bf7SJacob Keller #include "ice_dcb_lib.h" 100deb0bf7SJacob Keller #include "ice_flow.h" 110deb0bf7SJacob Keller #include "ice_eswitch.h" 120deb0bf7SJacob Keller #include "ice_virtchnl_allowlist.h" 130deb0bf7SJacob Keller #include "ice_flex_pipe.h" 140deb0bf7SJacob Keller #include "ice_vf_vsi_vlan_ops.h" 150deb0bf7SJacob Keller #include "ice_vlan.h" 160deb0bf7SJacob Keller 170deb0bf7SJacob Keller /** 180deb0bf7SJacob Keller * ice_free_vf_entries - Free all VF entries from the hash table 190deb0bf7SJacob Keller * @pf: pointer to the PF structure 200deb0bf7SJacob Keller * 210deb0bf7SJacob Keller * Iterate over the VF hash table, removing and releasing all VF entries. 220deb0bf7SJacob Keller * Called during VF teardown or as cleanup during failed VF initialization. 230deb0bf7SJacob Keller */ 240deb0bf7SJacob Keller static void ice_free_vf_entries(struct ice_pf *pf) 250deb0bf7SJacob Keller { 260deb0bf7SJacob Keller struct ice_vfs *vfs = &pf->vfs; 270deb0bf7SJacob Keller struct hlist_node *tmp; 280deb0bf7SJacob Keller struct ice_vf *vf; 290deb0bf7SJacob Keller unsigned int bkt; 300deb0bf7SJacob Keller 310deb0bf7SJacob Keller /* Remove all VFs from the hash table and release their main 320deb0bf7SJacob Keller * reference. Once all references to the VF are dropped, ice_put_vf() 330deb0bf7SJacob Keller * will call ice_release_vf which will remove the VF memory. 340deb0bf7SJacob Keller */ 350deb0bf7SJacob Keller lockdep_assert_held(&vfs->table_lock); 360deb0bf7SJacob Keller 370deb0bf7SJacob Keller hash_for_each_safe(vfs->table, bkt, tmp, vf, entry) { 380deb0bf7SJacob Keller hash_del_rcu(&vf->entry); 390deb0bf7SJacob Keller ice_put_vf(vf); 400deb0bf7SJacob Keller } 410deb0bf7SJacob Keller } 420deb0bf7SJacob Keller 430deb0bf7SJacob Keller /** 440deb0bf7SJacob Keller * ice_free_vf_res - Free a VF's resources 450deb0bf7SJacob Keller * @vf: pointer to the VF info 460deb0bf7SJacob Keller */ 470deb0bf7SJacob Keller static void ice_free_vf_res(struct ice_vf *vf) 480deb0bf7SJacob Keller { 490deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 500deb0bf7SJacob Keller int i, last_vector_idx; 510deb0bf7SJacob Keller 520deb0bf7SJacob Keller /* First, disable VF's configuration API to prevent OS from 530deb0bf7SJacob Keller * accessing the VF's VSI after it's freed or invalidated. 540deb0bf7SJacob Keller */ 550deb0bf7SJacob Keller clear_bit(ICE_VF_STATE_INIT, vf->vf_states); 560deb0bf7SJacob Keller ice_vf_fdir_exit(vf); 570deb0bf7SJacob Keller /* free VF control VSI */ 580deb0bf7SJacob Keller if (vf->ctrl_vsi_idx != ICE_NO_VSI) 590deb0bf7SJacob Keller ice_vf_ctrl_vsi_release(vf); 600deb0bf7SJacob Keller 610deb0bf7SJacob Keller /* free VSI and disconnect it from the parent uplink */ 620deb0bf7SJacob Keller if (vf->lan_vsi_idx != ICE_NO_VSI) { 630deb0bf7SJacob Keller ice_vf_vsi_release(vf); 640deb0bf7SJacob Keller vf->num_mac = 0; 650deb0bf7SJacob Keller } 660deb0bf7SJacob Keller 670deb0bf7SJacob Keller last_vector_idx = vf->first_vector_idx + pf->vfs.num_msix_per - 1; 680deb0bf7SJacob Keller 690deb0bf7SJacob Keller /* clear VF MDD event information */ 700deb0bf7SJacob Keller memset(&vf->mdd_tx_events, 0, sizeof(vf->mdd_tx_events)); 710deb0bf7SJacob Keller memset(&vf->mdd_rx_events, 0, sizeof(vf->mdd_rx_events)); 720deb0bf7SJacob Keller 730deb0bf7SJacob Keller /* Disable interrupts so that VF starts in a known state */ 740deb0bf7SJacob Keller for (i = vf->first_vector_idx; i <= last_vector_idx; i++) { 750deb0bf7SJacob Keller wr32(&pf->hw, GLINT_DYN_CTL(i), GLINT_DYN_CTL_CLEARPBA_M); 760deb0bf7SJacob Keller ice_flush(&pf->hw); 770deb0bf7SJacob Keller } 780deb0bf7SJacob Keller /* reset some of the state variables keeping track of the resources */ 790deb0bf7SJacob Keller clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states); 800deb0bf7SJacob Keller clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states); 810deb0bf7SJacob Keller } 820deb0bf7SJacob Keller 830deb0bf7SJacob Keller /** 840deb0bf7SJacob Keller * ice_dis_vf_mappings 850deb0bf7SJacob Keller * @vf: pointer to the VF structure 860deb0bf7SJacob Keller */ 870deb0bf7SJacob Keller static void ice_dis_vf_mappings(struct ice_vf *vf) 880deb0bf7SJacob Keller { 890deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 900deb0bf7SJacob Keller struct ice_vsi *vsi; 910deb0bf7SJacob Keller struct device *dev; 920deb0bf7SJacob Keller int first, last, v; 930deb0bf7SJacob Keller struct ice_hw *hw; 940deb0bf7SJacob Keller 950deb0bf7SJacob Keller hw = &pf->hw; 960deb0bf7SJacob Keller vsi = ice_get_vf_vsi(vf); 97baeb705fSJacob Keller if (WARN_ON(!vsi)) 98baeb705fSJacob Keller return; 990deb0bf7SJacob Keller 1000deb0bf7SJacob Keller dev = ice_pf_to_dev(pf); 1010deb0bf7SJacob Keller wr32(hw, VPINT_ALLOC(vf->vf_id), 0); 1020deb0bf7SJacob Keller wr32(hw, VPINT_ALLOC_PCI(vf->vf_id), 0); 1030deb0bf7SJacob Keller 1040deb0bf7SJacob Keller first = vf->first_vector_idx; 1050deb0bf7SJacob Keller last = first + pf->vfs.num_msix_per - 1; 1060deb0bf7SJacob Keller for (v = first; v <= last; v++) { 1070deb0bf7SJacob Keller u32 reg; 1080deb0bf7SJacob Keller 1090deb0bf7SJacob Keller reg = (((1 << GLINT_VECT2FUNC_IS_PF_S) & 1100deb0bf7SJacob Keller GLINT_VECT2FUNC_IS_PF_M) | 1110deb0bf7SJacob Keller ((hw->pf_id << GLINT_VECT2FUNC_PF_NUM_S) & 1120deb0bf7SJacob Keller GLINT_VECT2FUNC_PF_NUM_M)); 1130deb0bf7SJacob Keller wr32(hw, GLINT_VECT2FUNC(v), reg); 1140deb0bf7SJacob Keller } 1150deb0bf7SJacob Keller 1160deb0bf7SJacob Keller if (vsi->tx_mapping_mode == ICE_VSI_MAP_CONTIG) 1170deb0bf7SJacob Keller wr32(hw, VPLAN_TX_QBASE(vf->vf_id), 0); 1180deb0bf7SJacob Keller else 1190deb0bf7SJacob Keller dev_err(dev, "Scattered mode for VF Tx queues is not yet implemented\n"); 1200deb0bf7SJacob Keller 1210deb0bf7SJacob Keller if (vsi->rx_mapping_mode == ICE_VSI_MAP_CONTIG) 1220deb0bf7SJacob Keller wr32(hw, VPLAN_RX_QBASE(vf->vf_id), 0); 1230deb0bf7SJacob Keller else 1240deb0bf7SJacob Keller dev_err(dev, "Scattered mode for VF Rx queues is not yet implemented\n"); 1250deb0bf7SJacob Keller } 1260deb0bf7SJacob Keller 1270deb0bf7SJacob Keller /** 1280deb0bf7SJacob Keller * ice_sriov_free_msix_res - Reset/free any used MSIX resources 1290deb0bf7SJacob Keller * @pf: pointer to the PF structure 1300deb0bf7SJacob Keller * 1310deb0bf7SJacob Keller * Since no MSIX entries are taken from the pf->irq_tracker then just clear 1320deb0bf7SJacob Keller * the pf->sriov_base_vector. 1330deb0bf7SJacob Keller * 1340deb0bf7SJacob Keller * Returns 0 on success, and -EINVAL on error. 1350deb0bf7SJacob Keller */ 1360deb0bf7SJacob Keller static int ice_sriov_free_msix_res(struct ice_pf *pf) 1370deb0bf7SJacob Keller { 1380deb0bf7SJacob Keller struct ice_res_tracker *res; 1390deb0bf7SJacob Keller 1400deb0bf7SJacob Keller if (!pf) 1410deb0bf7SJacob Keller return -EINVAL; 1420deb0bf7SJacob Keller 1430deb0bf7SJacob Keller res = pf->irq_tracker; 1440deb0bf7SJacob Keller if (!res) 1450deb0bf7SJacob Keller return -EINVAL; 1460deb0bf7SJacob Keller 1470deb0bf7SJacob Keller /* give back irq_tracker resources used */ 1480deb0bf7SJacob Keller WARN_ON(pf->sriov_base_vector < res->num_entries); 1490deb0bf7SJacob Keller 1500deb0bf7SJacob Keller pf->sriov_base_vector = 0; 1510deb0bf7SJacob Keller 1520deb0bf7SJacob Keller return 0; 1530deb0bf7SJacob Keller } 1540deb0bf7SJacob Keller 1550deb0bf7SJacob Keller /** 1560deb0bf7SJacob Keller * ice_free_vfs - Free all VFs 1570deb0bf7SJacob Keller * @pf: pointer to the PF structure 1580deb0bf7SJacob Keller */ 1590deb0bf7SJacob Keller void ice_free_vfs(struct ice_pf *pf) 1600deb0bf7SJacob Keller { 1610deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 1620deb0bf7SJacob Keller struct ice_vfs *vfs = &pf->vfs; 1630deb0bf7SJacob Keller struct ice_hw *hw = &pf->hw; 1640deb0bf7SJacob Keller struct ice_vf *vf; 1650deb0bf7SJacob Keller unsigned int bkt; 1660deb0bf7SJacob Keller 1670deb0bf7SJacob Keller if (!ice_has_vfs(pf)) 1680deb0bf7SJacob Keller return; 1690deb0bf7SJacob Keller 1700deb0bf7SJacob Keller while (test_and_set_bit(ICE_VF_DIS, pf->state)) 1710deb0bf7SJacob Keller usleep_range(1000, 2000); 1720deb0bf7SJacob Keller 1730deb0bf7SJacob Keller /* Disable IOV before freeing resources. This lets any VF drivers 1740deb0bf7SJacob Keller * running in the host get themselves cleaned up before we yank 1750deb0bf7SJacob Keller * the carpet out from underneath their feet. 1760deb0bf7SJacob Keller */ 1770deb0bf7SJacob Keller if (!pci_vfs_assigned(pf->pdev)) 1780deb0bf7SJacob Keller pci_disable_sriov(pf->pdev); 1790deb0bf7SJacob Keller else 1800deb0bf7SJacob Keller dev_warn(dev, "VFs are assigned - not disabling SR-IOV\n"); 1810deb0bf7SJacob Keller 1820deb0bf7SJacob Keller mutex_lock(&vfs->table_lock); 1830deb0bf7SJacob Keller 1840deb0bf7SJacob Keller ice_eswitch_release(pf); 1850deb0bf7SJacob Keller 1860deb0bf7SJacob Keller ice_for_each_vf(pf, bkt, vf) { 1870deb0bf7SJacob Keller mutex_lock(&vf->cfg_lock); 1880deb0bf7SJacob Keller 1890deb0bf7SJacob Keller ice_dis_vf_qs(vf); 1900deb0bf7SJacob Keller 1910deb0bf7SJacob Keller if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) { 1920deb0bf7SJacob Keller /* disable VF qp mappings and set VF disable state */ 1930deb0bf7SJacob Keller ice_dis_vf_mappings(vf); 1940deb0bf7SJacob Keller set_bit(ICE_VF_STATE_DIS, vf->vf_states); 1950deb0bf7SJacob Keller ice_free_vf_res(vf); 1960deb0bf7SJacob Keller } 1970deb0bf7SJacob Keller 1980deb0bf7SJacob Keller if (!pci_vfs_assigned(pf->pdev)) { 1990deb0bf7SJacob Keller u32 reg_idx, bit_idx; 2000deb0bf7SJacob Keller 2010deb0bf7SJacob Keller reg_idx = (hw->func_caps.vf_base_id + vf->vf_id) / 32; 2020deb0bf7SJacob Keller bit_idx = (hw->func_caps.vf_base_id + vf->vf_id) % 32; 2030deb0bf7SJacob Keller wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx)); 2040deb0bf7SJacob Keller } 2050deb0bf7SJacob Keller 2060deb0bf7SJacob Keller /* clear malicious info since the VF is getting released */ 2078cd8a6b1SJacob Keller list_del(&vf->mbx_info.list_entry); 2080deb0bf7SJacob Keller 2090deb0bf7SJacob Keller mutex_unlock(&vf->cfg_lock); 2100deb0bf7SJacob Keller } 2110deb0bf7SJacob Keller 2120deb0bf7SJacob Keller if (ice_sriov_free_msix_res(pf)) 2130deb0bf7SJacob Keller dev_err(dev, "Failed to free MSIX resources used by SR-IOV\n"); 2140deb0bf7SJacob Keller 2150deb0bf7SJacob Keller vfs->num_qps_per = 0; 2160deb0bf7SJacob Keller ice_free_vf_entries(pf); 2170deb0bf7SJacob Keller 2180deb0bf7SJacob Keller mutex_unlock(&vfs->table_lock); 2190deb0bf7SJacob Keller 2200deb0bf7SJacob Keller clear_bit(ICE_VF_DIS, pf->state); 2210deb0bf7SJacob Keller clear_bit(ICE_FLAG_SRIOV_ENA, pf->flags); 2220deb0bf7SJacob Keller } 2230deb0bf7SJacob Keller 2240deb0bf7SJacob Keller /** 2250deb0bf7SJacob Keller * ice_vf_vsi_setup - Set up a VF VSI 2260deb0bf7SJacob Keller * @vf: VF to setup VSI for 2270deb0bf7SJacob Keller * 2280deb0bf7SJacob Keller * Returns pointer to the successfully allocated VSI struct on success, 2290deb0bf7SJacob Keller * otherwise returns NULL on failure. 2300deb0bf7SJacob Keller */ 2310deb0bf7SJacob Keller static struct ice_vsi *ice_vf_vsi_setup(struct ice_vf *vf) 2320deb0bf7SJacob Keller { 2335e509ab2SJacob Keller struct ice_vsi_cfg_params params = {}; 2340deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 2350deb0bf7SJacob Keller struct ice_vsi *vsi; 2360deb0bf7SJacob Keller 2375e509ab2SJacob Keller params.type = ICE_VSI_VF; 2385e509ab2SJacob Keller params.pi = ice_vf_get_port_info(vf); 2395e509ab2SJacob Keller params.vf = vf; 2405e509ab2SJacob Keller params.flags = ICE_VSI_FLAG_INIT; 2415e509ab2SJacob Keller 2425e509ab2SJacob Keller vsi = ice_vsi_setup(pf, ¶ms); 2430deb0bf7SJacob Keller 2440deb0bf7SJacob Keller if (!vsi) { 2450deb0bf7SJacob Keller dev_err(ice_pf_to_dev(pf), "Failed to create VF VSI\n"); 2460deb0bf7SJacob Keller ice_vf_invalidate_vsi(vf); 2470deb0bf7SJacob Keller return NULL; 2480deb0bf7SJacob Keller } 2490deb0bf7SJacob Keller 2500deb0bf7SJacob Keller vf->lan_vsi_idx = vsi->idx; 2510deb0bf7SJacob Keller vf->lan_vsi_num = vsi->vsi_num; 2520deb0bf7SJacob Keller 2530deb0bf7SJacob Keller return vsi; 2540deb0bf7SJacob Keller } 2550deb0bf7SJacob Keller 2560deb0bf7SJacob Keller /** 2570deb0bf7SJacob Keller * ice_calc_vf_first_vector_idx - Calculate MSIX vector index in the PF space 2580deb0bf7SJacob Keller * @pf: pointer to PF structure 2590deb0bf7SJacob Keller * @vf: pointer to VF that the first MSIX vector index is being calculated for 2600deb0bf7SJacob Keller * 2610deb0bf7SJacob Keller * This returns the first MSIX vector index in PF space that is used by this VF. 2620deb0bf7SJacob Keller * This index is used when accessing PF relative registers such as 2630deb0bf7SJacob Keller * GLINT_VECT2FUNC and GLINT_DYN_CTL. 2640deb0bf7SJacob Keller * This will always be the OICR index in the AVF driver so any functionality 2650deb0bf7SJacob Keller * using vf->first_vector_idx for queue configuration will have to increment by 2660deb0bf7SJacob Keller * 1 to avoid meddling with the OICR index. 2670deb0bf7SJacob Keller */ 2680deb0bf7SJacob Keller static int ice_calc_vf_first_vector_idx(struct ice_pf *pf, struct ice_vf *vf) 2690deb0bf7SJacob Keller { 2700deb0bf7SJacob Keller return pf->sriov_base_vector + vf->vf_id * pf->vfs.num_msix_per; 2710deb0bf7SJacob Keller } 2720deb0bf7SJacob Keller 2730deb0bf7SJacob Keller /** 2740deb0bf7SJacob Keller * ice_ena_vf_msix_mappings - enable VF MSIX mappings in hardware 2750deb0bf7SJacob Keller * @vf: VF to enable MSIX mappings for 2760deb0bf7SJacob Keller * 2770deb0bf7SJacob Keller * Some of the registers need to be indexed/configured using hardware global 2780deb0bf7SJacob Keller * device values and other registers need 0-based values, which represent PF 2790deb0bf7SJacob Keller * based values. 2800deb0bf7SJacob Keller */ 2810deb0bf7SJacob Keller static void ice_ena_vf_msix_mappings(struct ice_vf *vf) 2820deb0bf7SJacob Keller { 2830deb0bf7SJacob Keller int device_based_first_msix, device_based_last_msix; 2840deb0bf7SJacob Keller int pf_based_first_msix, pf_based_last_msix, v; 2850deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 2860deb0bf7SJacob Keller int device_based_vf_id; 2870deb0bf7SJacob Keller struct ice_hw *hw; 2880deb0bf7SJacob Keller u32 reg; 2890deb0bf7SJacob Keller 2900deb0bf7SJacob Keller hw = &pf->hw; 2910deb0bf7SJacob Keller pf_based_first_msix = vf->first_vector_idx; 2920deb0bf7SJacob Keller pf_based_last_msix = (pf_based_first_msix + pf->vfs.num_msix_per) - 1; 2930deb0bf7SJacob Keller 2940deb0bf7SJacob Keller device_based_first_msix = pf_based_first_msix + 2950deb0bf7SJacob Keller pf->hw.func_caps.common_cap.msix_vector_first_id; 2960deb0bf7SJacob Keller device_based_last_msix = 2970deb0bf7SJacob Keller (device_based_first_msix + pf->vfs.num_msix_per) - 1; 2980deb0bf7SJacob Keller device_based_vf_id = vf->vf_id + hw->func_caps.vf_base_id; 2990deb0bf7SJacob Keller 3000deb0bf7SJacob Keller reg = (((device_based_first_msix << VPINT_ALLOC_FIRST_S) & 3010deb0bf7SJacob Keller VPINT_ALLOC_FIRST_M) | 3020deb0bf7SJacob Keller ((device_based_last_msix << VPINT_ALLOC_LAST_S) & 3030deb0bf7SJacob Keller VPINT_ALLOC_LAST_M) | VPINT_ALLOC_VALID_M); 3040deb0bf7SJacob Keller wr32(hw, VPINT_ALLOC(vf->vf_id), reg); 3050deb0bf7SJacob Keller 3060deb0bf7SJacob Keller reg = (((device_based_first_msix << VPINT_ALLOC_PCI_FIRST_S) 3070deb0bf7SJacob Keller & VPINT_ALLOC_PCI_FIRST_M) | 3080deb0bf7SJacob Keller ((device_based_last_msix << VPINT_ALLOC_PCI_LAST_S) & 3090deb0bf7SJacob Keller VPINT_ALLOC_PCI_LAST_M) | VPINT_ALLOC_PCI_VALID_M); 3100deb0bf7SJacob Keller wr32(hw, VPINT_ALLOC_PCI(vf->vf_id), reg); 3110deb0bf7SJacob Keller 3120deb0bf7SJacob Keller /* map the interrupts to its functions */ 3130deb0bf7SJacob Keller for (v = pf_based_first_msix; v <= pf_based_last_msix; v++) { 3140deb0bf7SJacob Keller reg = (((device_based_vf_id << GLINT_VECT2FUNC_VF_NUM_S) & 3150deb0bf7SJacob Keller GLINT_VECT2FUNC_VF_NUM_M) | 3160deb0bf7SJacob Keller ((hw->pf_id << GLINT_VECT2FUNC_PF_NUM_S) & 3170deb0bf7SJacob Keller GLINT_VECT2FUNC_PF_NUM_M)); 3180deb0bf7SJacob Keller wr32(hw, GLINT_VECT2FUNC(v), reg); 3190deb0bf7SJacob Keller } 3200deb0bf7SJacob Keller 3210deb0bf7SJacob Keller /* Map mailbox interrupt to VF MSI-X vector 0 */ 3220deb0bf7SJacob Keller wr32(hw, VPINT_MBX_CTL(device_based_vf_id), VPINT_MBX_CTL_CAUSE_ENA_M); 3230deb0bf7SJacob Keller } 3240deb0bf7SJacob Keller 3250deb0bf7SJacob Keller /** 3260deb0bf7SJacob Keller * ice_ena_vf_q_mappings - enable Rx/Tx queue mappings for a VF 3270deb0bf7SJacob Keller * @vf: VF to enable the mappings for 3280deb0bf7SJacob Keller * @max_txq: max Tx queues allowed on the VF's VSI 3290deb0bf7SJacob Keller * @max_rxq: max Rx queues allowed on the VF's VSI 3300deb0bf7SJacob Keller */ 3310deb0bf7SJacob Keller static void ice_ena_vf_q_mappings(struct ice_vf *vf, u16 max_txq, u16 max_rxq) 3320deb0bf7SJacob Keller { 3330deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(vf->pf); 3340deb0bf7SJacob Keller struct ice_vsi *vsi = ice_get_vf_vsi(vf); 3350deb0bf7SJacob Keller struct ice_hw *hw = &vf->pf->hw; 3360deb0bf7SJacob Keller u32 reg; 3370deb0bf7SJacob Keller 338baeb705fSJacob Keller if (WARN_ON(!vsi)) 339baeb705fSJacob Keller return; 340baeb705fSJacob Keller 3410deb0bf7SJacob Keller /* set regardless of mapping mode */ 3420deb0bf7SJacob Keller wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_id), VPLAN_TXQ_MAPENA_TX_ENA_M); 3430deb0bf7SJacob Keller 3440deb0bf7SJacob Keller /* VF Tx queues allocation */ 3450deb0bf7SJacob Keller if (vsi->tx_mapping_mode == ICE_VSI_MAP_CONTIG) { 3460deb0bf7SJacob Keller /* set the VF PF Tx queue range 3470deb0bf7SJacob Keller * VFNUMQ value should be set to (number of queues - 1). A value 3480deb0bf7SJacob Keller * of 0 means 1 queue and a value of 255 means 256 queues 3490deb0bf7SJacob Keller */ 3500deb0bf7SJacob Keller reg = (((vsi->txq_map[0] << VPLAN_TX_QBASE_VFFIRSTQ_S) & 3510deb0bf7SJacob Keller VPLAN_TX_QBASE_VFFIRSTQ_M) | 3520deb0bf7SJacob Keller (((max_txq - 1) << VPLAN_TX_QBASE_VFNUMQ_S) & 3530deb0bf7SJacob Keller VPLAN_TX_QBASE_VFNUMQ_M)); 3540deb0bf7SJacob Keller wr32(hw, VPLAN_TX_QBASE(vf->vf_id), reg); 3550deb0bf7SJacob Keller } else { 3560deb0bf7SJacob Keller dev_err(dev, "Scattered mode for VF Tx queues is not yet implemented\n"); 3570deb0bf7SJacob Keller } 3580deb0bf7SJacob Keller 3590deb0bf7SJacob Keller /* set regardless of mapping mode */ 3600deb0bf7SJacob Keller wr32(hw, VPLAN_RXQ_MAPENA(vf->vf_id), VPLAN_RXQ_MAPENA_RX_ENA_M); 3610deb0bf7SJacob Keller 3620deb0bf7SJacob Keller /* VF Rx queues allocation */ 3630deb0bf7SJacob Keller if (vsi->rx_mapping_mode == ICE_VSI_MAP_CONTIG) { 3640deb0bf7SJacob Keller /* set the VF PF Rx queue range 3650deb0bf7SJacob Keller * VFNUMQ value should be set to (number of queues - 1). A value 3660deb0bf7SJacob Keller * of 0 means 1 queue and a value of 255 means 256 queues 3670deb0bf7SJacob Keller */ 3680deb0bf7SJacob Keller reg = (((vsi->rxq_map[0] << VPLAN_RX_QBASE_VFFIRSTQ_S) & 3690deb0bf7SJacob Keller VPLAN_RX_QBASE_VFFIRSTQ_M) | 3700deb0bf7SJacob Keller (((max_rxq - 1) << VPLAN_RX_QBASE_VFNUMQ_S) & 3710deb0bf7SJacob Keller VPLAN_RX_QBASE_VFNUMQ_M)); 3720deb0bf7SJacob Keller wr32(hw, VPLAN_RX_QBASE(vf->vf_id), reg); 3730deb0bf7SJacob Keller } else { 3740deb0bf7SJacob Keller dev_err(dev, "Scattered mode for VF Rx queues is not yet implemented\n"); 3750deb0bf7SJacob Keller } 3760deb0bf7SJacob Keller } 3770deb0bf7SJacob Keller 3780deb0bf7SJacob Keller /** 3790deb0bf7SJacob Keller * ice_ena_vf_mappings - enable VF MSIX and queue mapping 3800deb0bf7SJacob Keller * @vf: pointer to the VF structure 3810deb0bf7SJacob Keller */ 3820deb0bf7SJacob Keller static void ice_ena_vf_mappings(struct ice_vf *vf) 3830deb0bf7SJacob Keller { 3840deb0bf7SJacob Keller struct ice_vsi *vsi = ice_get_vf_vsi(vf); 3850deb0bf7SJacob Keller 386baeb705fSJacob Keller if (WARN_ON(!vsi)) 387baeb705fSJacob Keller return; 388baeb705fSJacob Keller 3890deb0bf7SJacob Keller ice_ena_vf_msix_mappings(vf); 3900deb0bf7SJacob Keller ice_ena_vf_q_mappings(vf, vsi->alloc_txq, vsi->alloc_rxq); 3910deb0bf7SJacob Keller } 3920deb0bf7SJacob Keller 3930deb0bf7SJacob Keller /** 3940deb0bf7SJacob Keller * ice_calc_vf_reg_idx - Calculate the VF's register index in the PF space 3950deb0bf7SJacob Keller * @vf: VF to calculate the register index for 3960deb0bf7SJacob Keller * @q_vector: a q_vector associated to the VF 3970deb0bf7SJacob Keller */ 3980deb0bf7SJacob Keller int ice_calc_vf_reg_idx(struct ice_vf *vf, struct ice_q_vector *q_vector) 3990deb0bf7SJacob Keller { 4000deb0bf7SJacob Keller struct ice_pf *pf; 4010deb0bf7SJacob Keller 4020deb0bf7SJacob Keller if (!vf || !q_vector) 4030deb0bf7SJacob Keller return -EINVAL; 4040deb0bf7SJacob Keller 4050deb0bf7SJacob Keller pf = vf->pf; 4060deb0bf7SJacob Keller 4070deb0bf7SJacob Keller /* always add one to account for the OICR being the first MSIX */ 4080deb0bf7SJacob Keller return pf->sriov_base_vector + pf->vfs.num_msix_per * vf->vf_id + 4090deb0bf7SJacob Keller q_vector->v_idx + 1; 4100deb0bf7SJacob Keller } 4110deb0bf7SJacob Keller 4120deb0bf7SJacob Keller /** 4130deb0bf7SJacob Keller * ice_get_max_valid_res_idx - Get the max valid resource index 4140deb0bf7SJacob Keller * @res: pointer to the resource to find the max valid index for 4150deb0bf7SJacob Keller * 4160deb0bf7SJacob Keller * Start from the end of the ice_res_tracker and return right when we find the 4170deb0bf7SJacob Keller * first res->list entry with the ICE_RES_VALID_BIT set. This function is only 4180deb0bf7SJacob Keller * valid for SR-IOV because it is the only consumer that manipulates the 4190deb0bf7SJacob Keller * res->end and this is always called when res->end is set to res->num_entries. 4200deb0bf7SJacob Keller */ 4210deb0bf7SJacob Keller static int ice_get_max_valid_res_idx(struct ice_res_tracker *res) 4220deb0bf7SJacob Keller { 4230deb0bf7SJacob Keller int i; 4240deb0bf7SJacob Keller 4250deb0bf7SJacob Keller if (!res) 4260deb0bf7SJacob Keller return -EINVAL; 4270deb0bf7SJacob Keller 4280deb0bf7SJacob Keller for (i = res->num_entries - 1; i >= 0; i--) 4290deb0bf7SJacob Keller if (res->list[i] & ICE_RES_VALID_BIT) 4300deb0bf7SJacob Keller return i; 4310deb0bf7SJacob Keller 4320deb0bf7SJacob Keller return 0; 4330deb0bf7SJacob Keller } 4340deb0bf7SJacob Keller 4350deb0bf7SJacob Keller /** 4360deb0bf7SJacob Keller * ice_sriov_set_msix_res - Set any used MSIX resources 4370deb0bf7SJacob Keller * @pf: pointer to PF structure 4380deb0bf7SJacob Keller * @num_msix_needed: number of MSIX vectors needed for all SR-IOV VFs 4390deb0bf7SJacob Keller * 4400deb0bf7SJacob Keller * This function allows SR-IOV resources to be taken from the end of the PF's 4410deb0bf7SJacob Keller * allowed HW MSIX vectors so that the irq_tracker will not be affected. We 4420deb0bf7SJacob Keller * just set the pf->sriov_base_vector and return success. 4430deb0bf7SJacob Keller * 4440deb0bf7SJacob Keller * If there are not enough resources available, return an error. This should 4450deb0bf7SJacob Keller * always be caught by ice_set_per_vf_res(). 4460deb0bf7SJacob Keller * 4470deb0bf7SJacob Keller * Return 0 on success, and -EINVAL when there are not enough MSIX vectors 4480deb0bf7SJacob Keller * in the PF's space available for SR-IOV. 4490deb0bf7SJacob Keller */ 4500deb0bf7SJacob Keller static int ice_sriov_set_msix_res(struct ice_pf *pf, u16 num_msix_needed) 4510deb0bf7SJacob Keller { 4520deb0bf7SJacob Keller u16 total_vectors = pf->hw.func_caps.common_cap.num_msix_vectors; 4530deb0bf7SJacob Keller int vectors_used = pf->irq_tracker->num_entries; 4540deb0bf7SJacob Keller int sriov_base_vector; 4550deb0bf7SJacob Keller 4560deb0bf7SJacob Keller sriov_base_vector = total_vectors - num_msix_needed; 4570deb0bf7SJacob Keller 4580deb0bf7SJacob Keller /* make sure we only grab irq_tracker entries from the list end and 4590deb0bf7SJacob Keller * that we have enough available MSIX vectors 4600deb0bf7SJacob Keller */ 4610deb0bf7SJacob Keller if (sriov_base_vector < vectors_used) 4620deb0bf7SJacob Keller return -EINVAL; 4630deb0bf7SJacob Keller 4640deb0bf7SJacob Keller pf->sriov_base_vector = sriov_base_vector; 4650deb0bf7SJacob Keller 4660deb0bf7SJacob Keller return 0; 4670deb0bf7SJacob Keller } 4680deb0bf7SJacob Keller 4690deb0bf7SJacob Keller /** 4700deb0bf7SJacob Keller * ice_set_per_vf_res - check if vectors and queues are available 4710deb0bf7SJacob Keller * @pf: pointer to the PF structure 4720deb0bf7SJacob Keller * @num_vfs: the number of SR-IOV VFs being configured 4730deb0bf7SJacob Keller * 4740deb0bf7SJacob Keller * First, determine HW interrupts from common pool. If we allocate fewer VFs, we 4750deb0bf7SJacob Keller * get more vectors and can enable more queues per VF. Note that this does not 4760deb0bf7SJacob Keller * grab any vectors from the SW pool already allocated. Also note, that all 4770deb0bf7SJacob Keller * vector counts include one for each VF's miscellaneous interrupt vector 4780deb0bf7SJacob Keller * (i.e. OICR). 4790deb0bf7SJacob Keller * 4800deb0bf7SJacob Keller * Minimum VFs - 2 vectors, 1 queue pair 4810deb0bf7SJacob Keller * Small VFs - 5 vectors, 4 queue pairs 4820deb0bf7SJacob Keller * Medium VFs - 17 vectors, 16 queue pairs 4830deb0bf7SJacob Keller * 4840deb0bf7SJacob Keller * Second, determine number of queue pairs per VF by starting with a pre-defined 4850deb0bf7SJacob Keller * maximum each VF supports. If this is not possible, then we adjust based on 4860deb0bf7SJacob Keller * queue pairs available on the device. 4870deb0bf7SJacob Keller * 4880deb0bf7SJacob Keller * Lastly, set queue and MSI-X VF variables tracked by the PF so it can be used 4890deb0bf7SJacob Keller * by each VF during VF initialization and reset. 4900deb0bf7SJacob Keller */ 4910deb0bf7SJacob Keller static int ice_set_per_vf_res(struct ice_pf *pf, u16 num_vfs) 4920deb0bf7SJacob Keller { 4930deb0bf7SJacob Keller int max_valid_res_idx = ice_get_max_valid_res_idx(pf->irq_tracker); 4940deb0bf7SJacob Keller u16 num_msix_per_vf, num_txq, num_rxq, avail_qs; 4950deb0bf7SJacob Keller int msix_avail_per_vf, msix_avail_for_sriov; 4960deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 49794ab2488SJacob Keller int err; 4980deb0bf7SJacob Keller 4990deb0bf7SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 5000deb0bf7SJacob Keller 50194ab2488SJacob Keller if (!num_vfs) 5020deb0bf7SJacob Keller return -EINVAL; 5030deb0bf7SJacob Keller 50494ab2488SJacob Keller if (max_valid_res_idx < 0) 50594ab2488SJacob Keller return -ENOSPC; 50694ab2488SJacob Keller 5070deb0bf7SJacob Keller /* determine MSI-X resources per VF */ 5080deb0bf7SJacob Keller msix_avail_for_sriov = pf->hw.func_caps.common_cap.num_msix_vectors - 5090deb0bf7SJacob Keller pf->irq_tracker->num_entries; 5100deb0bf7SJacob Keller msix_avail_per_vf = msix_avail_for_sriov / num_vfs; 5110deb0bf7SJacob Keller if (msix_avail_per_vf >= ICE_NUM_VF_MSIX_MED) { 5120deb0bf7SJacob Keller num_msix_per_vf = ICE_NUM_VF_MSIX_MED; 5130deb0bf7SJacob Keller } else if (msix_avail_per_vf >= ICE_NUM_VF_MSIX_SMALL) { 5140deb0bf7SJacob Keller num_msix_per_vf = ICE_NUM_VF_MSIX_SMALL; 5150deb0bf7SJacob Keller } else if (msix_avail_per_vf >= ICE_NUM_VF_MSIX_MULTIQ_MIN) { 5160deb0bf7SJacob Keller num_msix_per_vf = ICE_NUM_VF_MSIX_MULTIQ_MIN; 5170deb0bf7SJacob Keller } else if (msix_avail_per_vf >= ICE_MIN_INTR_PER_VF) { 5180deb0bf7SJacob Keller num_msix_per_vf = ICE_MIN_INTR_PER_VF; 5190deb0bf7SJacob Keller } else { 5200deb0bf7SJacob Keller dev_err(dev, "Only %d MSI-X interrupts available for SR-IOV. Not enough to support minimum of %d MSI-X interrupts per VF for %d VFs\n", 5210deb0bf7SJacob Keller msix_avail_for_sriov, ICE_MIN_INTR_PER_VF, 5220deb0bf7SJacob Keller num_vfs); 52394ab2488SJacob Keller return -ENOSPC; 5240deb0bf7SJacob Keller } 5250deb0bf7SJacob Keller 5260deb0bf7SJacob Keller num_txq = min_t(u16, num_msix_per_vf - ICE_NONQ_VECS_VF, 5270deb0bf7SJacob Keller ICE_MAX_RSS_QS_PER_VF); 5280deb0bf7SJacob Keller avail_qs = ice_get_avail_txq_count(pf) / num_vfs; 5290deb0bf7SJacob Keller if (!avail_qs) 5300deb0bf7SJacob Keller num_txq = 0; 5310deb0bf7SJacob Keller else if (num_txq > avail_qs) 5320deb0bf7SJacob Keller num_txq = rounddown_pow_of_two(avail_qs); 5330deb0bf7SJacob Keller 5340deb0bf7SJacob Keller num_rxq = min_t(u16, num_msix_per_vf - ICE_NONQ_VECS_VF, 5350deb0bf7SJacob Keller ICE_MAX_RSS_QS_PER_VF); 5360deb0bf7SJacob Keller avail_qs = ice_get_avail_rxq_count(pf) / num_vfs; 5370deb0bf7SJacob Keller if (!avail_qs) 5380deb0bf7SJacob Keller num_rxq = 0; 5390deb0bf7SJacob Keller else if (num_rxq > avail_qs) 5400deb0bf7SJacob Keller num_rxq = rounddown_pow_of_two(avail_qs); 5410deb0bf7SJacob Keller 5420deb0bf7SJacob Keller if (num_txq < ICE_MIN_QS_PER_VF || num_rxq < ICE_MIN_QS_PER_VF) { 5430deb0bf7SJacob Keller dev_err(dev, "Not enough queues to support minimum of %d queue pairs per VF for %d VFs\n", 5440deb0bf7SJacob Keller ICE_MIN_QS_PER_VF, num_vfs); 54594ab2488SJacob Keller return -ENOSPC; 5460deb0bf7SJacob Keller } 5470deb0bf7SJacob Keller 54894ab2488SJacob Keller err = ice_sriov_set_msix_res(pf, num_msix_per_vf * num_vfs); 54994ab2488SJacob Keller if (err) { 55094ab2488SJacob Keller dev_err(dev, "Unable to set MSI-X resources for %d VFs, err %d\n", 55194ab2488SJacob Keller num_vfs, err); 55294ab2488SJacob Keller return err; 5530deb0bf7SJacob Keller } 5540deb0bf7SJacob Keller 5550deb0bf7SJacob Keller /* only allow equal Tx/Rx queue count (i.e. queue pairs) */ 5560deb0bf7SJacob Keller pf->vfs.num_qps_per = min_t(int, num_txq, num_rxq); 5570deb0bf7SJacob Keller pf->vfs.num_msix_per = num_msix_per_vf; 5580deb0bf7SJacob Keller dev_info(dev, "Enabling %d VFs with %d vectors and %d queues per VF\n", 5590deb0bf7SJacob Keller num_vfs, pf->vfs.num_msix_per, pf->vfs.num_qps_per); 5600deb0bf7SJacob Keller 5610deb0bf7SJacob Keller return 0; 5620deb0bf7SJacob Keller } 5630deb0bf7SJacob Keller 5640deb0bf7SJacob Keller /** 5650deb0bf7SJacob Keller * ice_init_vf_vsi_res - initialize/setup VF VSI resources 5660deb0bf7SJacob Keller * @vf: VF to initialize/setup the VSI for 5670deb0bf7SJacob Keller * 5680deb0bf7SJacob Keller * This function creates a VSI for the VF, adds a VLAN 0 filter, and sets up the 5690deb0bf7SJacob Keller * VF VSI's broadcast filter and is only used during initial VF creation. 5700deb0bf7SJacob Keller */ 5710deb0bf7SJacob Keller static int ice_init_vf_vsi_res(struct ice_vf *vf) 5720deb0bf7SJacob Keller { 5730deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 5740deb0bf7SJacob Keller struct ice_vsi *vsi; 5750deb0bf7SJacob Keller int err; 5760deb0bf7SJacob Keller 5770deb0bf7SJacob Keller vf->first_vector_idx = ice_calc_vf_first_vector_idx(pf, vf); 5780deb0bf7SJacob Keller 5790deb0bf7SJacob Keller vsi = ice_vf_vsi_setup(vf); 5800deb0bf7SJacob Keller if (!vsi) 5810deb0bf7SJacob Keller return -ENOMEM; 5820deb0bf7SJacob Keller 583b1b56942SJacob Keller err = ice_vf_init_host_cfg(vf, vsi); 584b1b56942SJacob Keller if (err) 5850deb0bf7SJacob Keller goto release_vsi; 5860deb0bf7SJacob Keller 5870deb0bf7SJacob Keller return 0; 5880deb0bf7SJacob Keller 5890deb0bf7SJacob Keller release_vsi: 5900deb0bf7SJacob Keller ice_vf_vsi_release(vf); 5910deb0bf7SJacob Keller return err; 5920deb0bf7SJacob Keller } 5930deb0bf7SJacob Keller 5940deb0bf7SJacob Keller /** 5950deb0bf7SJacob Keller * ice_start_vfs - start VFs so they are ready to be used by SR-IOV 5960deb0bf7SJacob Keller * @pf: PF the VFs are associated with 5970deb0bf7SJacob Keller */ 5980deb0bf7SJacob Keller static int ice_start_vfs(struct ice_pf *pf) 5990deb0bf7SJacob Keller { 6000deb0bf7SJacob Keller struct ice_hw *hw = &pf->hw; 6010deb0bf7SJacob Keller unsigned int bkt, it_cnt; 6020deb0bf7SJacob Keller struct ice_vf *vf; 6030deb0bf7SJacob Keller int retval; 6040deb0bf7SJacob Keller 6050deb0bf7SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 6060deb0bf7SJacob Keller 6070deb0bf7SJacob Keller it_cnt = 0; 6080deb0bf7SJacob Keller ice_for_each_vf(pf, bkt, vf) { 6099c6f7878SJacob Keller vf->vf_ops->clear_reset_trigger(vf); 6100deb0bf7SJacob Keller 6110deb0bf7SJacob Keller retval = ice_init_vf_vsi_res(vf); 6120deb0bf7SJacob Keller if (retval) { 6130deb0bf7SJacob Keller dev_err(ice_pf_to_dev(pf), "Failed to initialize VSI resources for VF %d, error %d\n", 6140deb0bf7SJacob Keller vf->vf_id, retval); 6150deb0bf7SJacob Keller goto teardown; 6160deb0bf7SJacob Keller } 6170deb0bf7SJacob Keller 6180deb0bf7SJacob Keller set_bit(ICE_VF_STATE_INIT, vf->vf_states); 6190deb0bf7SJacob Keller ice_ena_vf_mappings(vf); 6200deb0bf7SJacob Keller wr32(hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_VFACTIVE); 6210deb0bf7SJacob Keller it_cnt++; 6220deb0bf7SJacob Keller } 6230deb0bf7SJacob Keller 6240deb0bf7SJacob Keller ice_flush(hw); 6250deb0bf7SJacob Keller return 0; 6260deb0bf7SJacob Keller 6270deb0bf7SJacob Keller teardown: 6280deb0bf7SJacob Keller ice_for_each_vf(pf, bkt, vf) { 6290deb0bf7SJacob Keller if (it_cnt == 0) 6300deb0bf7SJacob Keller break; 6310deb0bf7SJacob Keller 6320deb0bf7SJacob Keller ice_dis_vf_mappings(vf); 6330deb0bf7SJacob Keller ice_vf_vsi_release(vf); 6340deb0bf7SJacob Keller it_cnt--; 6350deb0bf7SJacob Keller } 6360deb0bf7SJacob Keller 6370deb0bf7SJacob Keller return retval; 6380deb0bf7SJacob Keller } 6390deb0bf7SJacob Keller 6400deb0bf7SJacob Keller /** 6419c6f7878SJacob Keller * ice_sriov_free_vf - Free VF memory after all references are dropped 6429c6f7878SJacob Keller * @vf: pointer to VF to free 6439c6f7878SJacob Keller * 6449c6f7878SJacob Keller * Called by ice_put_vf through ice_release_vf once the last reference to a VF 6459c6f7878SJacob Keller * structure has been dropped. 6469c6f7878SJacob Keller */ 6479c6f7878SJacob Keller static void ice_sriov_free_vf(struct ice_vf *vf) 6489c6f7878SJacob Keller { 6499c6f7878SJacob Keller mutex_destroy(&vf->cfg_lock); 6509c6f7878SJacob Keller 6519c6f7878SJacob Keller kfree_rcu(vf, rcu); 6529c6f7878SJacob Keller } 6539c6f7878SJacob Keller 6549c6f7878SJacob Keller /** 655fa4a15c8SJacob Keller * ice_sriov_clear_reset_state - clears VF Reset status register 656fa4a15c8SJacob Keller * @vf: the vf to configure 657fa4a15c8SJacob Keller */ 658fa4a15c8SJacob Keller static void ice_sriov_clear_reset_state(struct ice_vf *vf) 659fa4a15c8SJacob Keller { 660fa4a15c8SJacob Keller struct ice_hw *hw = &vf->pf->hw; 661fa4a15c8SJacob Keller 662fa4a15c8SJacob Keller /* Clear the reset status register so that VF immediately sees that 663fa4a15c8SJacob Keller * the device is resetting, even if hardware hasn't yet gotten around 664fa4a15c8SJacob Keller * to clearing VFGEN_RSTAT for us. 665fa4a15c8SJacob Keller */ 666fa4a15c8SJacob Keller wr32(hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_INPROGRESS); 667fa4a15c8SJacob Keller } 668fa4a15c8SJacob Keller 669fa4a15c8SJacob Keller /** 6709c6f7878SJacob Keller * ice_sriov_clear_mbx_register - clears SRIOV VF's mailbox registers 6719c6f7878SJacob Keller * @vf: the vf to configure 6729c6f7878SJacob Keller */ 6739c6f7878SJacob Keller static void ice_sriov_clear_mbx_register(struct ice_vf *vf) 6749c6f7878SJacob Keller { 6759c6f7878SJacob Keller struct ice_pf *pf = vf->pf; 6769c6f7878SJacob Keller 6779c6f7878SJacob Keller wr32(&pf->hw, VF_MBX_ARQLEN(vf->vf_id), 0); 6789c6f7878SJacob Keller wr32(&pf->hw, VF_MBX_ATQLEN(vf->vf_id), 0); 6799c6f7878SJacob Keller } 6809c6f7878SJacob Keller 6819c6f7878SJacob Keller /** 6829c6f7878SJacob Keller * ice_sriov_trigger_reset_register - trigger VF reset for SRIOV VF 6839c6f7878SJacob Keller * @vf: pointer to VF structure 6849c6f7878SJacob Keller * @is_vflr: true if reset occurred due to VFLR 6859c6f7878SJacob Keller * 6869c6f7878SJacob Keller * Trigger and cleanup after a VF reset for a SR-IOV VF. 6879c6f7878SJacob Keller */ 6889c6f7878SJacob Keller static void ice_sriov_trigger_reset_register(struct ice_vf *vf, bool is_vflr) 6899c6f7878SJacob Keller { 6909c6f7878SJacob Keller struct ice_pf *pf = vf->pf; 6919c6f7878SJacob Keller u32 reg, reg_idx, bit_idx; 6929c6f7878SJacob Keller unsigned int vf_abs_id, i; 6939c6f7878SJacob Keller struct device *dev; 6949c6f7878SJacob Keller struct ice_hw *hw; 6959c6f7878SJacob Keller 6969c6f7878SJacob Keller dev = ice_pf_to_dev(pf); 6979c6f7878SJacob Keller hw = &pf->hw; 6989c6f7878SJacob Keller vf_abs_id = vf->vf_id + hw->func_caps.vf_base_id; 6999c6f7878SJacob Keller 7009c6f7878SJacob Keller /* In the case of a VFLR, HW has already reset the VF and we just need 7019c6f7878SJacob Keller * to clean up. Otherwise we must first trigger the reset using the 7029c6f7878SJacob Keller * VFRTRIG register. 7039c6f7878SJacob Keller */ 7049c6f7878SJacob Keller if (!is_vflr) { 7059c6f7878SJacob Keller reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id)); 7069c6f7878SJacob Keller reg |= VPGEN_VFRTRIG_VFSWR_M; 7079c6f7878SJacob Keller wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg); 7089c6f7878SJacob Keller } 7099c6f7878SJacob Keller 7109c6f7878SJacob Keller /* clear the VFLR bit in GLGEN_VFLRSTAT */ 7119c6f7878SJacob Keller reg_idx = (vf_abs_id) / 32; 7129c6f7878SJacob Keller bit_idx = (vf_abs_id) % 32; 7139c6f7878SJacob Keller wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx)); 7149c6f7878SJacob Keller ice_flush(hw); 7159c6f7878SJacob Keller 7169c6f7878SJacob Keller wr32(hw, PF_PCI_CIAA, 7179c6f7878SJacob Keller VF_DEVICE_STATUS | (vf_abs_id << PF_PCI_CIAA_VF_NUM_S)); 7189c6f7878SJacob Keller for (i = 0; i < ICE_PCI_CIAD_WAIT_COUNT; i++) { 7199c6f7878SJacob Keller reg = rd32(hw, PF_PCI_CIAD); 7209c6f7878SJacob Keller /* no transactions pending so stop polling */ 7219c6f7878SJacob Keller if ((reg & VF_TRANS_PENDING_M) == 0) 7229c6f7878SJacob Keller break; 7239c6f7878SJacob Keller 7249c6f7878SJacob Keller dev_err(dev, "VF %u PCI transactions stuck\n", vf->vf_id); 7259c6f7878SJacob Keller udelay(ICE_PCI_CIAD_WAIT_DELAY_US); 7269c6f7878SJacob Keller } 7279c6f7878SJacob Keller } 7289c6f7878SJacob Keller 7299c6f7878SJacob Keller /** 7309c6f7878SJacob Keller * ice_sriov_poll_reset_status - poll SRIOV VF reset status 7319c6f7878SJacob Keller * @vf: pointer to VF structure 7329c6f7878SJacob Keller * 7339c6f7878SJacob Keller * Returns true when reset is successful, else returns false 7349c6f7878SJacob Keller */ 7359c6f7878SJacob Keller static bool ice_sriov_poll_reset_status(struct ice_vf *vf) 7369c6f7878SJacob Keller { 7379c6f7878SJacob Keller struct ice_pf *pf = vf->pf; 7389c6f7878SJacob Keller unsigned int i; 7399c6f7878SJacob Keller u32 reg; 7409c6f7878SJacob Keller 7419c6f7878SJacob Keller for (i = 0; i < 10; i++) { 7429c6f7878SJacob Keller /* VF reset requires driver to first reset the VF and then 7439c6f7878SJacob Keller * poll the status register to make sure that the reset 7449c6f7878SJacob Keller * completed successfully. 7459c6f7878SJacob Keller */ 7469c6f7878SJacob Keller reg = rd32(&pf->hw, VPGEN_VFRSTAT(vf->vf_id)); 7479c6f7878SJacob Keller if (reg & VPGEN_VFRSTAT_VFRD_M) 7489c6f7878SJacob Keller return true; 7499c6f7878SJacob Keller 7509c6f7878SJacob Keller /* only sleep if the reset is not done */ 7519c6f7878SJacob Keller usleep_range(10, 20); 7529c6f7878SJacob Keller } 7539c6f7878SJacob Keller return false; 7549c6f7878SJacob Keller } 7559c6f7878SJacob Keller 7569c6f7878SJacob Keller /** 7579c6f7878SJacob Keller * ice_sriov_clear_reset_trigger - enable VF to access hardware 7589c6f7878SJacob Keller * @vf: VF to enabled hardware access for 7599c6f7878SJacob Keller */ 7609c6f7878SJacob Keller static void ice_sriov_clear_reset_trigger(struct ice_vf *vf) 7619c6f7878SJacob Keller { 7629c6f7878SJacob Keller struct ice_hw *hw = &vf->pf->hw; 7639c6f7878SJacob Keller u32 reg; 7649c6f7878SJacob Keller 7659c6f7878SJacob Keller reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id)); 7669c6f7878SJacob Keller reg &= ~VPGEN_VFRTRIG_VFSWR_M; 7679c6f7878SJacob Keller wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg); 7689c6f7878SJacob Keller ice_flush(hw); 7699c6f7878SJacob Keller } 7709c6f7878SJacob Keller 7719c6f7878SJacob Keller /** 7725531bb85SJacob Keller * ice_sriov_create_vsi - Create a new VSI for a VF 7735531bb85SJacob Keller * @vf: VF to create the VSI for 7749c6f7878SJacob Keller * 7755531bb85SJacob Keller * This is called by ice_vf_recreate_vsi to create the new VSI after the old 7765531bb85SJacob Keller * VSI has been released. 7779c6f7878SJacob Keller */ 7785531bb85SJacob Keller static int ice_sriov_create_vsi(struct ice_vf *vf) 7799c6f7878SJacob Keller { 7805531bb85SJacob Keller struct ice_vsi *vsi; 7819c6f7878SJacob Keller 7825531bb85SJacob Keller vsi = ice_vf_vsi_setup(vf); 7835531bb85SJacob Keller if (!vsi) 7849c6f7878SJacob Keller return -ENOMEM; 7859c6f7878SJacob Keller 7869c6f7878SJacob Keller return 0; 7879c6f7878SJacob Keller } 7889c6f7878SJacob Keller 7899c6f7878SJacob Keller /** 7909c6f7878SJacob Keller * ice_sriov_post_vsi_rebuild - tasks to do after the VF's VSI have been rebuilt 7919c6f7878SJacob Keller * @vf: VF to perform tasks on 7929c6f7878SJacob Keller */ 7939c6f7878SJacob Keller static void ice_sriov_post_vsi_rebuild(struct ice_vf *vf) 7949c6f7878SJacob Keller { 7959c6f7878SJacob Keller ice_ena_vf_mappings(vf); 7969c6f7878SJacob Keller wr32(&vf->pf->hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_VFACTIVE); 7979c6f7878SJacob Keller } 7989c6f7878SJacob Keller 7999c6f7878SJacob Keller static const struct ice_vf_ops ice_sriov_vf_ops = { 8009c6f7878SJacob Keller .reset_type = ICE_VF_RESET, 8019c6f7878SJacob Keller .free = ice_sriov_free_vf, 802fa4a15c8SJacob Keller .clear_reset_state = ice_sriov_clear_reset_state, 8039c6f7878SJacob Keller .clear_mbx_register = ice_sriov_clear_mbx_register, 8049c6f7878SJacob Keller .trigger_reset_register = ice_sriov_trigger_reset_register, 8059c6f7878SJacob Keller .poll_reset_status = ice_sriov_poll_reset_status, 8069c6f7878SJacob Keller .clear_reset_trigger = ice_sriov_clear_reset_trigger, 807537dfe06SJacob Keller .irq_close = NULL, 8085531bb85SJacob Keller .create_vsi = ice_sriov_create_vsi, 8099c6f7878SJacob Keller .post_vsi_rebuild = ice_sriov_post_vsi_rebuild, 8109c6f7878SJacob Keller }; 8119c6f7878SJacob Keller 8129c6f7878SJacob Keller /** 8130deb0bf7SJacob Keller * ice_create_vf_entries - Allocate and insert VF entries 8140deb0bf7SJacob Keller * @pf: pointer to the PF structure 8150deb0bf7SJacob Keller * @num_vfs: the number of VFs to allocate 8160deb0bf7SJacob Keller * 8170deb0bf7SJacob Keller * Allocate new VF entries and insert them into the hash table. Set some 8180deb0bf7SJacob Keller * basic default fields for initializing the new VFs. 8190deb0bf7SJacob Keller * 8200deb0bf7SJacob Keller * After this function exits, the hash table will have num_vfs entries 8210deb0bf7SJacob Keller * inserted. 8220deb0bf7SJacob Keller * 8230deb0bf7SJacob Keller * Returns 0 on success or an integer error code on failure. 8240deb0bf7SJacob Keller */ 8250deb0bf7SJacob Keller static int ice_create_vf_entries(struct ice_pf *pf, u16 num_vfs) 8260deb0bf7SJacob Keller { 8270deb0bf7SJacob Keller struct ice_vfs *vfs = &pf->vfs; 8280deb0bf7SJacob Keller struct ice_vf *vf; 8290deb0bf7SJacob Keller u16 vf_id; 8300deb0bf7SJacob Keller int err; 8310deb0bf7SJacob Keller 8320deb0bf7SJacob Keller lockdep_assert_held(&vfs->table_lock); 8330deb0bf7SJacob Keller 8340deb0bf7SJacob Keller for (vf_id = 0; vf_id < num_vfs; vf_id++) { 8350deb0bf7SJacob Keller vf = kzalloc(sizeof(*vf), GFP_KERNEL); 8360deb0bf7SJacob Keller if (!vf) { 8370deb0bf7SJacob Keller err = -ENOMEM; 8380deb0bf7SJacob Keller goto err_free_entries; 8390deb0bf7SJacob Keller } 8400deb0bf7SJacob Keller kref_init(&vf->refcnt); 8410deb0bf7SJacob Keller 8420deb0bf7SJacob Keller vf->pf = pf; 8430deb0bf7SJacob Keller vf->vf_id = vf_id; 8440deb0bf7SJacob Keller 8459c6f7878SJacob Keller /* set sriov vf ops for VFs created during SRIOV flow */ 8469c6f7878SJacob Keller vf->vf_ops = &ice_sriov_vf_ops; 8479c6f7878SJacob Keller 848b5dcff1fSJacob Keller ice_initialize_vf_entry(vf); 849b5dcff1fSJacob Keller 8500deb0bf7SJacob Keller vf->vf_sw_id = pf->first_sw; 8510deb0bf7SJacob Keller 8520deb0bf7SJacob Keller hash_add_rcu(vfs->table, &vf->entry, vf_id); 8530deb0bf7SJacob Keller } 8540deb0bf7SJacob Keller 8550deb0bf7SJacob Keller return 0; 8560deb0bf7SJacob Keller 8570deb0bf7SJacob Keller err_free_entries: 8580deb0bf7SJacob Keller ice_free_vf_entries(pf); 8590deb0bf7SJacob Keller return err; 8600deb0bf7SJacob Keller } 8610deb0bf7SJacob Keller 8620deb0bf7SJacob Keller /** 8630deb0bf7SJacob Keller * ice_ena_vfs - enable VFs so they are ready to be used 8640deb0bf7SJacob Keller * @pf: pointer to the PF structure 8650deb0bf7SJacob Keller * @num_vfs: number of VFs to enable 8660deb0bf7SJacob Keller */ 8670deb0bf7SJacob Keller static int ice_ena_vfs(struct ice_pf *pf, u16 num_vfs) 8680deb0bf7SJacob Keller { 8690deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 8700deb0bf7SJacob Keller struct ice_hw *hw = &pf->hw; 8710deb0bf7SJacob Keller int ret; 8720deb0bf7SJacob Keller 8730deb0bf7SJacob Keller /* Disable global interrupt 0 so we don't try to handle the VFLR. */ 8740deb0bf7SJacob Keller wr32(hw, GLINT_DYN_CTL(pf->oicr_idx), 8750deb0bf7SJacob Keller ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S); 8760deb0bf7SJacob Keller set_bit(ICE_OICR_INTR_DIS, pf->state); 8770deb0bf7SJacob Keller ice_flush(hw); 8780deb0bf7SJacob Keller 8790deb0bf7SJacob Keller ret = pci_enable_sriov(pf->pdev, num_vfs); 8800deb0bf7SJacob Keller if (ret) 8810deb0bf7SJacob Keller goto err_unroll_intr; 8820deb0bf7SJacob Keller 8830deb0bf7SJacob Keller mutex_lock(&pf->vfs.table_lock); 8840deb0bf7SJacob Keller 88594ab2488SJacob Keller ret = ice_set_per_vf_res(pf, num_vfs); 88694ab2488SJacob Keller if (ret) { 88794ab2488SJacob Keller dev_err(dev, "Not enough resources for %d VFs, err %d. Try with fewer number of VFs\n", 88894ab2488SJacob Keller num_vfs, ret); 8890deb0bf7SJacob Keller goto err_unroll_sriov; 8900deb0bf7SJacob Keller } 8910deb0bf7SJacob Keller 8920deb0bf7SJacob Keller ret = ice_create_vf_entries(pf, num_vfs); 8930deb0bf7SJacob Keller if (ret) { 8940deb0bf7SJacob Keller dev_err(dev, "Failed to allocate VF entries for %d VFs\n", 8950deb0bf7SJacob Keller num_vfs); 8960deb0bf7SJacob Keller goto err_unroll_sriov; 8970deb0bf7SJacob Keller } 8980deb0bf7SJacob Keller 89994ab2488SJacob Keller ret = ice_start_vfs(pf); 90094ab2488SJacob Keller if (ret) { 90194ab2488SJacob Keller dev_err(dev, "Failed to start %d VFs, err %d\n", num_vfs, ret); 9020deb0bf7SJacob Keller ret = -EAGAIN; 9030deb0bf7SJacob Keller goto err_unroll_vf_entries; 9040deb0bf7SJacob Keller } 9050deb0bf7SJacob Keller 9060deb0bf7SJacob Keller clear_bit(ICE_VF_DIS, pf->state); 9070deb0bf7SJacob Keller 9080deb0bf7SJacob Keller ret = ice_eswitch_configure(pf); 9092b369448SJacob Keller if (ret) { 9102b369448SJacob Keller dev_err(dev, "Failed to configure eswitch, err %d\n", ret); 9110deb0bf7SJacob Keller goto err_unroll_sriov; 9122b369448SJacob Keller } 9130deb0bf7SJacob Keller 9140deb0bf7SJacob Keller /* rearm global interrupts */ 9150deb0bf7SJacob Keller if (test_and_clear_bit(ICE_OICR_INTR_DIS, pf->state)) 9160deb0bf7SJacob Keller ice_irq_dynamic_ena(hw, NULL, NULL); 9170deb0bf7SJacob Keller 9180deb0bf7SJacob Keller mutex_unlock(&pf->vfs.table_lock); 9190deb0bf7SJacob Keller 9200deb0bf7SJacob Keller return 0; 9210deb0bf7SJacob Keller 9220deb0bf7SJacob Keller err_unroll_vf_entries: 9230deb0bf7SJacob Keller ice_free_vf_entries(pf); 9240deb0bf7SJacob Keller err_unroll_sriov: 9250deb0bf7SJacob Keller mutex_unlock(&pf->vfs.table_lock); 9260deb0bf7SJacob Keller pci_disable_sriov(pf->pdev); 9270deb0bf7SJacob Keller err_unroll_intr: 9280deb0bf7SJacob Keller /* rearm interrupts here */ 9290deb0bf7SJacob Keller ice_irq_dynamic_ena(hw, NULL, NULL); 9300deb0bf7SJacob Keller clear_bit(ICE_OICR_INTR_DIS, pf->state); 9310deb0bf7SJacob Keller return ret; 9320deb0bf7SJacob Keller } 9330deb0bf7SJacob Keller 9340deb0bf7SJacob Keller /** 9350deb0bf7SJacob Keller * ice_pci_sriov_ena - Enable or change number of VFs 9360deb0bf7SJacob Keller * @pf: pointer to the PF structure 9370deb0bf7SJacob Keller * @num_vfs: number of VFs to allocate 9380deb0bf7SJacob Keller * 9390deb0bf7SJacob Keller * Returns 0 on success and negative on failure 9400deb0bf7SJacob Keller */ 9410deb0bf7SJacob Keller static int ice_pci_sriov_ena(struct ice_pf *pf, int num_vfs) 9420deb0bf7SJacob Keller { 9430deb0bf7SJacob Keller int pre_existing_vfs = pci_num_vf(pf->pdev); 9440deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 9450deb0bf7SJacob Keller int err; 9460deb0bf7SJacob Keller 9470deb0bf7SJacob Keller if (pre_existing_vfs && pre_existing_vfs != num_vfs) 9480deb0bf7SJacob Keller ice_free_vfs(pf); 9490deb0bf7SJacob Keller else if (pre_existing_vfs && pre_existing_vfs == num_vfs) 9500deb0bf7SJacob Keller return 0; 9510deb0bf7SJacob Keller 9520deb0bf7SJacob Keller if (num_vfs > pf->vfs.num_supported) { 9530deb0bf7SJacob Keller dev_err(dev, "Can't enable %d VFs, max VFs supported is %d\n", 9540deb0bf7SJacob Keller num_vfs, pf->vfs.num_supported); 9550deb0bf7SJacob Keller return -EOPNOTSUPP; 9560deb0bf7SJacob Keller } 9570deb0bf7SJacob Keller 9580deb0bf7SJacob Keller dev_info(dev, "Enabling %d VFs\n", num_vfs); 9590deb0bf7SJacob Keller err = ice_ena_vfs(pf, num_vfs); 9600deb0bf7SJacob Keller if (err) { 9610deb0bf7SJacob Keller dev_err(dev, "Failed to enable SR-IOV: %d\n", err); 9620deb0bf7SJacob Keller return err; 9630deb0bf7SJacob Keller } 9640deb0bf7SJacob Keller 9650deb0bf7SJacob Keller set_bit(ICE_FLAG_SRIOV_ENA, pf->flags); 9660deb0bf7SJacob Keller return 0; 9670deb0bf7SJacob Keller } 9680deb0bf7SJacob Keller 9690deb0bf7SJacob Keller /** 9700deb0bf7SJacob Keller * ice_check_sriov_allowed - check if SR-IOV is allowed based on various checks 9710deb0bf7SJacob Keller * @pf: PF to enabled SR-IOV on 9720deb0bf7SJacob Keller */ 9730deb0bf7SJacob Keller static int ice_check_sriov_allowed(struct ice_pf *pf) 9740deb0bf7SJacob Keller { 9750deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 9760deb0bf7SJacob Keller 9770deb0bf7SJacob Keller if (!test_bit(ICE_FLAG_SRIOV_CAPABLE, pf->flags)) { 9780deb0bf7SJacob Keller dev_err(dev, "This device is not capable of SR-IOV\n"); 9790deb0bf7SJacob Keller return -EOPNOTSUPP; 9800deb0bf7SJacob Keller } 9810deb0bf7SJacob Keller 9820deb0bf7SJacob Keller if (ice_is_safe_mode(pf)) { 9830deb0bf7SJacob Keller dev_err(dev, "SR-IOV cannot be configured - Device is in Safe Mode\n"); 9840deb0bf7SJacob Keller return -EOPNOTSUPP; 9850deb0bf7SJacob Keller } 9860deb0bf7SJacob Keller 9870deb0bf7SJacob Keller if (!ice_pf_state_is_nominal(pf)) { 9880deb0bf7SJacob Keller dev_err(dev, "Cannot enable SR-IOV, device not ready\n"); 9890deb0bf7SJacob Keller return -EBUSY; 9900deb0bf7SJacob Keller } 9910deb0bf7SJacob Keller 9920deb0bf7SJacob Keller return 0; 9930deb0bf7SJacob Keller } 9940deb0bf7SJacob Keller 9950deb0bf7SJacob Keller /** 9960deb0bf7SJacob Keller * ice_sriov_configure - Enable or change number of VFs via sysfs 9970deb0bf7SJacob Keller * @pdev: pointer to a pci_dev structure 9980deb0bf7SJacob Keller * @num_vfs: number of VFs to allocate or 0 to free VFs 9990deb0bf7SJacob Keller * 10000deb0bf7SJacob Keller * This function is called when the user updates the number of VFs in sysfs. On 10010deb0bf7SJacob Keller * success return whatever num_vfs was set to by the caller. Return negative on 10020deb0bf7SJacob Keller * failure. 10030deb0bf7SJacob Keller */ 10040deb0bf7SJacob Keller int ice_sriov_configure(struct pci_dev *pdev, int num_vfs) 10050deb0bf7SJacob Keller { 10060deb0bf7SJacob Keller struct ice_pf *pf = pci_get_drvdata(pdev); 10070deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 10080deb0bf7SJacob Keller int err; 10090deb0bf7SJacob Keller 10100deb0bf7SJacob Keller err = ice_check_sriov_allowed(pf); 10110deb0bf7SJacob Keller if (err) 10120deb0bf7SJacob Keller return err; 10130deb0bf7SJacob Keller 10140deb0bf7SJacob Keller if (!num_vfs) { 10150deb0bf7SJacob Keller if (!pci_vfs_assigned(pdev)) { 10160deb0bf7SJacob Keller ice_free_vfs(pf); 10170deb0bf7SJacob Keller if (pf->lag) 10180deb0bf7SJacob Keller ice_enable_lag(pf->lag); 10190deb0bf7SJacob Keller return 0; 10200deb0bf7SJacob Keller } 10210deb0bf7SJacob Keller 10220deb0bf7SJacob Keller dev_err(dev, "can't free VFs because some are assigned to VMs.\n"); 10230deb0bf7SJacob Keller return -EBUSY; 10240deb0bf7SJacob Keller } 10250deb0bf7SJacob Keller 10268cd8a6b1SJacob Keller ice_mbx_init_snapshot(&pf->hw); 10270deb0bf7SJacob Keller 10280deb0bf7SJacob Keller err = ice_pci_sriov_ena(pf, num_vfs); 1029*4bdf5f25SJacob Keller if (err) 10300deb0bf7SJacob Keller return err; 10310deb0bf7SJacob Keller 10320deb0bf7SJacob Keller if (pf->lag) 10330deb0bf7SJacob Keller ice_disable_lag(pf->lag); 10340deb0bf7SJacob Keller return num_vfs; 10350deb0bf7SJacob Keller } 10360deb0bf7SJacob Keller 10370deb0bf7SJacob Keller /** 10380deb0bf7SJacob Keller * ice_process_vflr_event - Free VF resources via IRQ calls 10390deb0bf7SJacob Keller * @pf: pointer to the PF structure 10400deb0bf7SJacob Keller * 10410deb0bf7SJacob Keller * called from the VFLR IRQ handler to 10420deb0bf7SJacob Keller * free up VF resources and state variables 10430deb0bf7SJacob Keller */ 10440deb0bf7SJacob Keller void ice_process_vflr_event(struct ice_pf *pf) 10450deb0bf7SJacob Keller { 10460deb0bf7SJacob Keller struct ice_hw *hw = &pf->hw; 10470deb0bf7SJacob Keller struct ice_vf *vf; 10480deb0bf7SJacob Keller unsigned int bkt; 10490deb0bf7SJacob Keller u32 reg; 10500deb0bf7SJacob Keller 10510deb0bf7SJacob Keller if (!test_and_clear_bit(ICE_VFLR_EVENT_PENDING, pf->state) || 10520deb0bf7SJacob Keller !ice_has_vfs(pf)) 10530deb0bf7SJacob Keller return; 10540deb0bf7SJacob Keller 10550deb0bf7SJacob Keller mutex_lock(&pf->vfs.table_lock); 10560deb0bf7SJacob Keller ice_for_each_vf(pf, bkt, vf) { 10570deb0bf7SJacob Keller u32 reg_idx, bit_idx; 10580deb0bf7SJacob Keller 10590deb0bf7SJacob Keller reg_idx = (hw->func_caps.vf_base_id + vf->vf_id) / 32; 10600deb0bf7SJacob Keller bit_idx = (hw->func_caps.vf_base_id + vf->vf_id) % 32; 10610deb0bf7SJacob Keller /* read GLGEN_VFLRSTAT register to find out the flr VFs */ 10620deb0bf7SJacob Keller reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx)); 1063f5f085c0SJacob Keller if (reg & BIT(bit_idx)) 10640deb0bf7SJacob Keller /* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */ 1065f5f085c0SJacob Keller ice_reset_vf(vf, ICE_VF_RESET_VFLR | ICE_VF_RESET_LOCK); 10660deb0bf7SJacob Keller } 10670deb0bf7SJacob Keller mutex_unlock(&pf->vfs.table_lock); 10680deb0bf7SJacob Keller } 10690deb0bf7SJacob Keller 10700deb0bf7SJacob Keller /** 10710deb0bf7SJacob Keller * ice_get_vf_from_pfq - get the VF who owns the PF space queue passed in 10720deb0bf7SJacob Keller * @pf: PF used to index all VFs 10730deb0bf7SJacob Keller * @pfq: queue index relative to the PF's function space 10740deb0bf7SJacob Keller * 10750deb0bf7SJacob Keller * If no VF is found who owns the pfq then return NULL, otherwise return a 10760deb0bf7SJacob Keller * pointer to the VF who owns the pfq 10770deb0bf7SJacob Keller * 10780deb0bf7SJacob Keller * If this function returns non-NULL, it acquires a reference count of the VF 10790deb0bf7SJacob Keller * structure. The caller is responsible for calling ice_put_vf() to drop this 10800deb0bf7SJacob Keller * reference. 10810deb0bf7SJacob Keller */ 10820deb0bf7SJacob Keller static struct ice_vf *ice_get_vf_from_pfq(struct ice_pf *pf, u16 pfq) 10830deb0bf7SJacob Keller { 10840deb0bf7SJacob Keller struct ice_vf *vf; 10850deb0bf7SJacob Keller unsigned int bkt; 10860deb0bf7SJacob Keller 10870deb0bf7SJacob Keller rcu_read_lock(); 10880deb0bf7SJacob Keller ice_for_each_vf_rcu(pf, bkt, vf) { 10890deb0bf7SJacob Keller struct ice_vsi *vsi; 10900deb0bf7SJacob Keller u16 rxq_idx; 10910deb0bf7SJacob Keller 10920deb0bf7SJacob Keller vsi = ice_get_vf_vsi(vf); 1093baeb705fSJacob Keller if (!vsi) 1094baeb705fSJacob Keller continue; 10950deb0bf7SJacob Keller 10960deb0bf7SJacob Keller ice_for_each_rxq(vsi, rxq_idx) 10970deb0bf7SJacob Keller if (vsi->rxq_map[rxq_idx] == pfq) { 10980deb0bf7SJacob Keller struct ice_vf *found; 10990deb0bf7SJacob Keller 11000deb0bf7SJacob Keller if (kref_get_unless_zero(&vf->refcnt)) 11010deb0bf7SJacob Keller found = vf; 11020deb0bf7SJacob Keller else 11030deb0bf7SJacob Keller found = NULL; 11040deb0bf7SJacob Keller rcu_read_unlock(); 11050deb0bf7SJacob Keller return found; 11060deb0bf7SJacob Keller } 11070deb0bf7SJacob Keller } 11080deb0bf7SJacob Keller rcu_read_unlock(); 11090deb0bf7SJacob Keller 11100deb0bf7SJacob Keller return NULL; 11110deb0bf7SJacob Keller } 11120deb0bf7SJacob Keller 11130deb0bf7SJacob Keller /** 11140deb0bf7SJacob Keller * ice_globalq_to_pfq - convert from global queue index to PF space queue index 11150deb0bf7SJacob Keller * @pf: PF used for conversion 11160deb0bf7SJacob Keller * @globalq: global queue index used to convert to PF space queue index 11170deb0bf7SJacob Keller */ 11180deb0bf7SJacob Keller static u32 ice_globalq_to_pfq(struct ice_pf *pf, u32 globalq) 11190deb0bf7SJacob Keller { 11200deb0bf7SJacob Keller return globalq - pf->hw.func_caps.common_cap.rxq_first_id; 11210deb0bf7SJacob Keller } 11220deb0bf7SJacob Keller 11230deb0bf7SJacob Keller /** 11240deb0bf7SJacob Keller * ice_vf_lan_overflow_event - handle LAN overflow event for a VF 11250deb0bf7SJacob Keller * @pf: PF that the LAN overflow event happened on 11260deb0bf7SJacob Keller * @event: structure holding the event information for the LAN overflow event 11270deb0bf7SJacob Keller * 11280deb0bf7SJacob Keller * Determine if the LAN overflow event was caused by a VF queue. If it was not 11290deb0bf7SJacob Keller * caused by a VF, do nothing. If a VF caused this LAN overflow event trigger a 11300deb0bf7SJacob Keller * reset on the offending VF. 11310deb0bf7SJacob Keller */ 11320deb0bf7SJacob Keller void 11330deb0bf7SJacob Keller ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) 11340deb0bf7SJacob Keller { 11350deb0bf7SJacob Keller u32 gldcb_rtctq, queue; 11360deb0bf7SJacob Keller struct ice_vf *vf; 11370deb0bf7SJacob Keller 11380deb0bf7SJacob Keller gldcb_rtctq = le32_to_cpu(event->desc.params.lan_overflow.prtdcb_ruptq); 11390deb0bf7SJacob Keller dev_dbg(ice_pf_to_dev(pf), "GLDCB_RTCTQ: 0x%08x\n", gldcb_rtctq); 11400deb0bf7SJacob Keller 11410deb0bf7SJacob Keller /* event returns device global Rx queue number */ 11420deb0bf7SJacob Keller queue = (gldcb_rtctq & GLDCB_RTCTQ_RXQNUM_M) >> 11430deb0bf7SJacob Keller GLDCB_RTCTQ_RXQNUM_S; 11440deb0bf7SJacob Keller 11450deb0bf7SJacob Keller vf = ice_get_vf_from_pfq(pf, ice_globalq_to_pfq(pf, queue)); 11460deb0bf7SJacob Keller if (!vf) 11470deb0bf7SJacob Keller return; 11480deb0bf7SJacob Keller 1149f5f085c0SJacob Keller ice_reset_vf(vf, ICE_VF_RESET_NOTIFY | ICE_VF_RESET_LOCK); 11500deb0bf7SJacob Keller ice_put_vf(vf); 11510deb0bf7SJacob Keller } 11520deb0bf7SJacob Keller 11530deb0bf7SJacob Keller /** 11540deb0bf7SJacob Keller * ice_set_vf_spoofchk 11550deb0bf7SJacob Keller * @netdev: network interface device structure 11560deb0bf7SJacob Keller * @vf_id: VF identifier 11570deb0bf7SJacob Keller * @ena: flag to enable or disable feature 11580deb0bf7SJacob Keller * 11590deb0bf7SJacob Keller * Enable or disable VF spoof checking 11600deb0bf7SJacob Keller */ 11610deb0bf7SJacob Keller int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena) 11620deb0bf7SJacob Keller { 11630deb0bf7SJacob Keller struct ice_netdev_priv *np = netdev_priv(netdev); 11640deb0bf7SJacob Keller struct ice_pf *pf = np->vsi->back; 11650deb0bf7SJacob Keller struct ice_vsi *vf_vsi; 11660deb0bf7SJacob Keller struct device *dev; 11670deb0bf7SJacob Keller struct ice_vf *vf; 11680deb0bf7SJacob Keller int ret; 11690deb0bf7SJacob Keller 11700deb0bf7SJacob Keller dev = ice_pf_to_dev(pf); 11710deb0bf7SJacob Keller 11720deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 11730deb0bf7SJacob Keller if (!vf) 11740deb0bf7SJacob Keller return -EINVAL; 11750deb0bf7SJacob Keller 11760deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 11770deb0bf7SJacob Keller if (ret) 11780deb0bf7SJacob Keller goto out_put_vf; 11790deb0bf7SJacob Keller 11800deb0bf7SJacob Keller vf_vsi = ice_get_vf_vsi(vf); 11810deb0bf7SJacob Keller if (!vf_vsi) { 11820deb0bf7SJacob Keller netdev_err(netdev, "VSI %d for VF %d is null\n", 11830deb0bf7SJacob Keller vf->lan_vsi_idx, vf->vf_id); 11840deb0bf7SJacob Keller ret = -EINVAL; 11850deb0bf7SJacob Keller goto out_put_vf; 11860deb0bf7SJacob Keller } 11870deb0bf7SJacob Keller 11880deb0bf7SJacob Keller if (vf_vsi->type != ICE_VSI_VF) { 11890deb0bf7SJacob Keller netdev_err(netdev, "Type %d of VSI %d for VF %d is no ICE_VSI_VF\n", 11900deb0bf7SJacob Keller vf_vsi->type, vf_vsi->vsi_num, vf->vf_id); 11910deb0bf7SJacob Keller ret = -ENODEV; 11920deb0bf7SJacob Keller goto out_put_vf; 11930deb0bf7SJacob Keller } 11940deb0bf7SJacob Keller 11950deb0bf7SJacob Keller if (ena == vf->spoofchk) { 11960deb0bf7SJacob Keller dev_dbg(dev, "VF spoofchk already %s\n", ena ? "ON" : "OFF"); 11970deb0bf7SJacob Keller ret = 0; 11980deb0bf7SJacob Keller goto out_put_vf; 11990deb0bf7SJacob Keller } 12000deb0bf7SJacob Keller 1201a8ea6d86SJacob Keller ret = ice_vsi_apply_spoofchk(vf_vsi, ena); 12020deb0bf7SJacob Keller if (ret) 12030deb0bf7SJacob Keller dev_err(dev, "Failed to set spoofchk %s for VF %d VSI %d\n error %d\n", 12040deb0bf7SJacob Keller ena ? "ON" : "OFF", vf->vf_id, vf_vsi->vsi_num, ret); 12050deb0bf7SJacob Keller else 12060deb0bf7SJacob Keller vf->spoofchk = ena; 12070deb0bf7SJacob Keller 12080deb0bf7SJacob Keller out_put_vf: 12090deb0bf7SJacob Keller ice_put_vf(vf); 12100deb0bf7SJacob Keller return ret; 12110deb0bf7SJacob Keller } 12120deb0bf7SJacob Keller 12130deb0bf7SJacob Keller /** 12140deb0bf7SJacob Keller * ice_get_vf_cfg 12150deb0bf7SJacob Keller * @netdev: network interface device structure 12160deb0bf7SJacob Keller * @vf_id: VF identifier 12170deb0bf7SJacob Keller * @ivi: VF configuration structure 12180deb0bf7SJacob Keller * 12190deb0bf7SJacob Keller * return VF configuration 12200deb0bf7SJacob Keller */ 12210deb0bf7SJacob Keller int 12220deb0bf7SJacob Keller ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) 12230deb0bf7SJacob Keller { 12240deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 12250deb0bf7SJacob Keller struct ice_vf *vf; 12260deb0bf7SJacob Keller int ret; 12270deb0bf7SJacob Keller 12280deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 12290deb0bf7SJacob Keller if (!vf) 12300deb0bf7SJacob Keller return -EINVAL; 12310deb0bf7SJacob Keller 12320deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 12330deb0bf7SJacob Keller if (ret) 12340deb0bf7SJacob Keller goto out_put_vf; 12350deb0bf7SJacob Keller 12360deb0bf7SJacob Keller ivi->vf = vf_id; 1237e0645311SJacob Keller ether_addr_copy(ivi->mac, vf->hw_lan_addr); 12380deb0bf7SJacob Keller 12390deb0bf7SJacob Keller /* VF configuration for VLAN and applicable QoS */ 12400deb0bf7SJacob Keller ivi->vlan = ice_vf_get_port_vlan_id(vf); 12410deb0bf7SJacob Keller ivi->qos = ice_vf_get_port_vlan_prio(vf); 12420deb0bf7SJacob Keller if (ice_vf_is_port_vlan_ena(vf)) 12430deb0bf7SJacob Keller ivi->vlan_proto = cpu_to_be16(ice_vf_get_port_vlan_tpid(vf)); 12440deb0bf7SJacob Keller 12450deb0bf7SJacob Keller ivi->trusted = vf->trusted; 12460deb0bf7SJacob Keller ivi->spoofchk = vf->spoofchk; 12470deb0bf7SJacob Keller if (!vf->link_forced) 12480deb0bf7SJacob Keller ivi->linkstate = IFLA_VF_LINK_STATE_AUTO; 12490deb0bf7SJacob Keller else if (vf->link_up) 12500deb0bf7SJacob Keller ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE; 12510deb0bf7SJacob Keller else 12520deb0bf7SJacob Keller ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE; 12530deb0bf7SJacob Keller ivi->max_tx_rate = vf->max_tx_rate; 12540deb0bf7SJacob Keller ivi->min_tx_rate = vf->min_tx_rate; 12550deb0bf7SJacob Keller 12560deb0bf7SJacob Keller out_put_vf: 12570deb0bf7SJacob Keller ice_put_vf(vf); 12580deb0bf7SJacob Keller return ret; 12590deb0bf7SJacob Keller } 12600deb0bf7SJacob Keller 12610deb0bf7SJacob Keller /** 12620deb0bf7SJacob Keller * ice_set_vf_mac 12630deb0bf7SJacob Keller * @netdev: network interface device structure 12640deb0bf7SJacob Keller * @vf_id: VF identifier 12650deb0bf7SJacob Keller * @mac: MAC address 12660deb0bf7SJacob Keller * 12670deb0bf7SJacob Keller * program VF MAC address 12680deb0bf7SJacob Keller */ 12690deb0bf7SJacob Keller int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) 12700deb0bf7SJacob Keller { 12710deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 12720deb0bf7SJacob Keller struct ice_vf *vf; 12730deb0bf7SJacob Keller int ret; 12740deb0bf7SJacob Keller 12750deb0bf7SJacob Keller if (is_multicast_ether_addr(mac)) { 12760deb0bf7SJacob Keller netdev_err(netdev, "%pM not a valid unicast address\n", mac); 12770deb0bf7SJacob Keller return -EINVAL; 12780deb0bf7SJacob Keller } 12790deb0bf7SJacob Keller 12800deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 12810deb0bf7SJacob Keller if (!vf) 12820deb0bf7SJacob Keller return -EINVAL; 12830deb0bf7SJacob Keller 12840deb0bf7SJacob Keller /* nothing left to do, unicast MAC already set */ 1285e0645311SJacob Keller if (ether_addr_equal(vf->dev_lan_addr, mac) && 1286e0645311SJacob Keller ether_addr_equal(vf->hw_lan_addr, mac)) { 12870deb0bf7SJacob Keller ret = 0; 12880deb0bf7SJacob Keller goto out_put_vf; 12890deb0bf7SJacob Keller } 12900deb0bf7SJacob Keller 12910deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 12920deb0bf7SJacob Keller if (ret) 12930deb0bf7SJacob Keller goto out_put_vf; 12940deb0bf7SJacob Keller 12950deb0bf7SJacob Keller mutex_lock(&vf->cfg_lock); 12960deb0bf7SJacob Keller 12970deb0bf7SJacob Keller /* VF is notified of its new MAC via the PF's response to the 12980deb0bf7SJacob Keller * VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset 12990deb0bf7SJacob Keller */ 1300e0645311SJacob Keller ether_addr_copy(vf->dev_lan_addr, mac); 1301e0645311SJacob Keller ether_addr_copy(vf->hw_lan_addr, mac); 13020deb0bf7SJacob Keller if (is_zero_ether_addr(mac)) { 13030deb0bf7SJacob Keller /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ 13040deb0bf7SJacob Keller vf->pf_set_mac = false; 13050deb0bf7SJacob Keller netdev_info(netdev, "Removing MAC on VF %d. VF driver will be reinitialized\n", 13060deb0bf7SJacob Keller vf->vf_id); 13070deb0bf7SJacob Keller } else { 13080deb0bf7SJacob Keller /* PF will add MAC rule for the VF */ 13090deb0bf7SJacob Keller vf->pf_set_mac = true; 13100deb0bf7SJacob Keller netdev_info(netdev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", 13110deb0bf7SJacob Keller mac, vf_id); 13120deb0bf7SJacob Keller } 13130deb0bf7SJacob Keller 13149dbb33daSJacob Keller ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); 13150deb0bf7SJacob Keller mutex_unlock(&vf->cfg_lock); 13160deb0bf7SJacob Keller 13170deb0bf7SJacob Keller out_put_vf: 13180deb0bf7SJacob Keller ice_put_vf(vf); 13190deb0bf7SJacob Keller return ret; 13200deb0bf7SJacob Keller } 13210deb0bf7SJacob Keller 13220deb0bf7SJacob Keller /** 13230deb0bf7SJacob Keller * ice_set_vf_trust 13240deb0bf7SJacob Keller * @netdev: network interface device structure 13250deb0bf7SJacob Keller * @vf_id: VF identifier 13260deb0bf7SJacob Keller * @trusted: Boolean value to enable/disable trusted VF 13270deb0bf7SJacob Keller * 13280deb0bf7SJacob Keller * Enable or disable a given VF as trusted 13290deb0bf7SJacob Keller */ 13300deb0bf7SJacob Keller int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted) 13310deb0bf7SJacob Keller { 13320deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 13330deb0bf7SJacob Keller struct ice_vf *vf; 13340deb0bf7SJacob Keller int ret; 13350deb0bf7SJacob Keller 13360deb0bf7SJacob Keller if (ice_is_eswitch_mode_switchdev(pf)) { 13370deb0bf7SJacob Keller dev_info(ice_pf_to_dev(pf), "Trusted VF is forbidden in switchdev mode\n"); 13380deb0bf7SJacob Keller return -EOPNOTSUPP; 13390deb0bf7SJacob Keller } 13400deb0bf7SJacob Keller 13410deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 13420deb0bf7SJacob Keller if (!vf) 13430deb0bf7SJacob Keller return -EINVAL; 13440deb0bf7SJacob Keller 13450deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 13460deb0bf7SJacob Keller if (ret) 13470deb0bf7SJacob Keller goto out_put_vf; 13480deb0bf7SJacob Keller 13490deb0bf7SJacob Keller /* Check if already trusted */ 13500deb0bf7SJacob Keller if (trusted == vf->trusted) { 13510deb0bf7SJacob Keller ret = 0; 13520deb0bf7SJacob Keller goto out_put_vf; 13530deb0bf7SJacob Keller } 13540deb0bf7SJacob Keller 13550deb0bf7SJacob Keller mutex_lock(&vf->cfg_lock); 13560deb0bf7SJacob Keller 13570deb0bf7SJacob Keller vf->trusted = trusted; 13589dbb33daSJacob Keller ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); 13590deb0bf7SJacob Keller dev_info(ice_pf_to_dev(pf), "VF %u is now %strusted\n", 13600deb0bf7SJacob Keller vf_id, trusted ? "" : "un"); 13610deb0bf7SJacob Keller 13620deb0bf7SJacob Keller mutex_unlock(&vf->cfg_lock); 13630deb0bf7SJacob Keller 13640deb0bf7SJacob Keller out_put_vf: 13650deb0bf7SJacob Keller ice_put_vf(vf); 13660deb0bf7SJacob Keller return ret; 13670deb0bf7SJacob Keller } 13680deb0bf7SJacob Keller 13690deb0bf7SJacob Keller /** 13700deb0bf7SJacob Keller * ice_set_vf_link_state 13710deb0bf7SJacob Keller * @netdev: network interface device structure 13720deb0bf7SJacob Keller * @vf_id: VF identifier 13730deb0bf7SJacob Keller * @link_state: required link state 13740deb0bf7SJacob Keller * 13750deb0bf7SJacob Keller * Set VF's link state, irrespective of physical link state status 13760deb0bf7SJacob Keller */ 13770deb0bf7SJacob Keller int ice_set_vf_link_state(struct net_device *netdev, int vf_id, int link_state) 13780deb0bf7SJacob Keller { 13790deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 13800deb0bf7SJacob Keller struct ice_vf *vf; 13810deb0bf7SJacob Keller int ret; 13820deb0bf7SJacob Keller 13830deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 13840deb0bf7SJacob Keller if (!vf) 13850deb0bf7SJacob Keller return -EINVAL; 13860deb0bf7SJacob Keller 13870deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 13880deb0bf7SJacob Keller if (ret) 13890deb0bf7SJacob Keller goto out_put_vf; 13900deb0bf7SJacob Keller 13910deb0bf7SJacob Keller switch (link_state) { 13920deb0bf7SJacob Keller case IFLA_VF_LINK_STATE_AUTO: 13930deb0bf7SJacob Keller vf->link_forced = false; 13940deb0bf7SJacob Keller break; 13950deb0bf7SJacob Keller case IFLA_VF_LINK_STATE_ENABLE: 13960deb0bf7SJacob Keller vf->link_forced = true; 13970deb0bf7SJacob Keller vf->link_up = true; 13980deb0bf7SJacob Keller break; 13990deb0bf7SJacob Keller case IFLA_VF_LINK_STATE_DISABLE: 14000deb0bf7SJacob Keller vf->link_forced = true; 14010deb0bf7SJacob Keller vf->link_up = false; 14020deb0bf7SJacob Keller break; 14030deb0bf7SJacob Keller default: 14040deb0bf7SJacob Keller ret = -EINVAL; 14050deb0bf7SJacob Keller goto out_put_vf; 14060deb0bf7SJacob Keller } 14070deb0bf7SJacob Keller 14080deb0bf7SJacob Keller ice_vc_notify_vf_link_state(vf); 14090deb0bf7SJacob Keller 14100deb0bf7SJacob Keller out_put_vf: 14110deb0bf7SJacob Keller ice_put_vf(vf); 14120deb0bf7SJacob Keller return ret; 14130deb0bf7SJacob Keller } 14140deb0bf7SJacob Keller 14150deb0bf7SJacob Keller /** 14160deb0bf7SJacob Keller * ice_calc_all_vfs_min_tx_rate - calculate cumulative min Tx rate on all VFs 14170deb0bf7SJacob Keller * @pf: PF associated with VFs 14180deb0bf7SJacob Keller */ 14190deb0bf7SJacob Keller static int ice_calc_all_vfs_min_tx_rate(struct ice_pf *pf) 14200deb0bf7SJacob Keller { 14210deb0bf7SJacob Keller struct ice_vf *vf; 14220deb0bf7SJacob Keller unsigned int bkt; 14230deb0bf7SJacob Keller int rate = 0; 14240deb0bf7SJacob Keller 14250deb0bf7SJacob Keller rcu_read_lock(); 14260deb0bf7SJacob Keller ice_for_each_vf_rcu(pf, bkt, vf) 14270deb0bf7SJacob Keller rate += vf->min_tx_rate; 14280deb0bf7SJacob Keller rcu_read_unlock(); 14290deb0bf7SJacob Keller 14300deb0bf7SJacob Keller return rate; 14310deb0bf7SJacob Keller } 14320deb0bf7SJacob Keller 14330deb0bf7SJacob Keller /** 14340deb0bf7SJacob Keller * ice_min_tx_rate_oversubscribed - check if min Tx rate causes oversubscription 14350deb0bf7SJacob Keller * @vf: VF trying to configure min_tx_rate 14360deb0bf7SJacob Keller * @min_tx_rate: min Tx rate in Mbps 14370deb0bf7SJacob Keller * 14380deb0bf7SJacob Keller * Check if the min_tx_rate being passed in will cause oversubscription of total 14390deb0bf7SJacob Keller * min_tx_rate based on the current link speed and all other VFs configured 14400deb0bf7SJacob Keller * min_tx_rate 14410deb0bf7SJacob Keller * 14420deb0bf7SJacob Keller * Return true if the passed min_tx_rate would cause oversubscription, else 14430deb0bf7SJacob Keller * return false 14440deb0bf7SJacob Keller */ 14450deb0bf7SJacob Keller static bool 14460deb0bf7SJacob Keller ice_min_tx_rate_oversubscribed(struct ice_vf *vf, int min_tx_rate) 14470deb0bf7SJacob Keller { 1448baeb705fSJacob Keller struct ice_vsi *vsi = ice_get_vf_vsi(vf); 1449baeb705fSJacob Keller int all_vfs_min_tx_rate; 1450baeb705fSJacob Keller int link_speed_mbps; 1451baeb705fSJacob Keller 1452baeb705fSJacob Keller if (WARN_ON(!vsi)) 1453baeb705fSJacob Keller return false; 1454baeb705fSJacob Keller 1455baeb705fSJacob Keller link_speed_mbps = ice_get_link_speed_mbps(vsi); 1456baeb705fSJacob Keller all_vfs_min_tx_rate = ice_calc_all_vfs_min_tx_rate(vf->pf); 14570deb0bf7SJacob Keller 14580deb0bf7SJacob Keller /* this VF's previous rate is being overwritten */ 14590deb0bf7SJacob Keller all_vfs_min_tx_rate -= vf->min_tx_rate; 14600deb0bf7SJacob Keller 14610deb0bf7SJacob Keller if (all_vfs_min_tx_rate + min_tx_rate > link_speed_mbps) { 14620deb0bf7SJacob Keller dev_err(ice_pf_to_dev(vf->pf), "min_tx_rate of %d Mbps on VF %u would cause oversubscription of %d Mbps based on the current link speed %d Mbps\n", 14630deb0bf7SJacob Keller min_tx_rate, vf->vf_id, 14640deb0bf7SJacob Keller all_vfs_min_tx_rate + min_tx_rate - link_speed_mbps, 14650deb0bf7SJacob Keller link_speed_mbps); 14660deb0bf7SJacob Keller return true; 14670deb0bf7SJacob Keller } 14680deb0bf7SJacob Keller 14690deb0bf7SJacob Keller return false; 14700deb0bf7SJacob Keller } 14710deb0bf7SJacob Keller 14720deb0bf7SJacob Keller /** 14730deb0bf7SJacob Keller * ice_set_vf_bw - set min/max VF bandwidth 14740deb0bf7SJacob Keller * @netdev: network interface device structure 14750deb0bf7SJacob Keller * @vf_id: VF identifier 14760deb0bf7SJacob Keller * @min_tx_rate: Minimum Tx rate in Mbps 14770deb0bf7SJacob Keller * @max_tx_rate: Maximum Tx rate in Mbps 14780deb0bf7SJacob Keller */ 14790deb0bf7SJacob Keller int 14800deb0bf7SJacob Keller ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, 14810deb0bf7SJacob Keller int max_tx_rate) 14820deb0bf7SJacob Keller { 14830deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 14840deb0bf7SJacob Keller struct ice_vsi *vsi; 14850deb0bf7SJacob Keller struct device *dev; 14860deb0bf7SJacob Keller struct ice_vf *vf; 14870deb0bf7SJacob Keller int ret; 14880deb0bf7SJacob Keller 14890deb0bf7SJacob Keller dev = ice_pf_to_dev(pf); 14900deb0bf7SJacob Keller 14910deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 14920deb0bf7SJacob Keller if (!vf) 14930deb0bf7SJacob Keller return -EINVAL; 14940deb0bf7SJacob Keller 14950deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 14960deb0bf7SJacob Keller if (ret) 14970deb0bf7SJacob Keller goto out_put_vf; 14980deb0bf7SJacob Keller 14990deb0bf7SJacob Keller vsi = ice_get_vf_vsi(vf); 1500baeb705fSJacob Keller if (!vsi) { 1501baeb705fSJacob Keller ret = -EINVAL; 1502baeb705fSJacob Keller goto out_put_vf; 1503baeb705fSJacob Keller } 15040deb0bf7SJacob Keller 15050deb0bf7SJacob Keller if (min_tx_rate && ice_is_dcb_active(pf)) { 15060deb0bf7SJacob Keller dev_err(dev, "DCB on PF is currently enabled. VF min Tx rate limiting not allowed on this PF.\n"); 15070deb0bf7SJacob Keller ret = -EOPNOTSUPP; 15080deb0bf7SJacob Keller goto out_put_vf; 15090deb0bf7SJacob Keller } 15100deb0bf7SJacob Keller 15110deb0bf7SJacob Keller if (ice_min_tx_rate_oversubscribed(vf, min_tx_rate)) { 15120deb0bf7SJacob Keller ret = -EINVAL; 15130deb0bf7SJacob Keller goto out_put_vf; 15140deb0bf7SJacob Keller } 15150deb0bf7SJacob Keller 15160deb0bf7SJacob Keller if (vf->min_tx_rate != (unsigned int)min_tx_rate) { 15170deb0bf7SJacob Keller ret = ice_set_min_bw_limit(vsi, (u64)min_tx_rate * 1000); 15180deb0bf7SJacob Keller if (ret) { 15190deb0bf7SJacob Keller dev_err(dev, "Unable to set min-tx-rate for VF %d\n", 15200deb0bf7SJacob Keller vf->vf_id); 15210deb0bf7SJacob Keller goto out_put_vf; 15220deb0bf7SJacob Keller } 15230deb0bf7SJacob Keller 15240deb0bf7SJacob Keller vf->min_tx_rate = min_tx_rate; 15250deb0bf7SJacob Keller } 15260deb0bf7SJacob Keller 15270deb0bf7SJacob Keller if (vf->max_tx_rate != (unsigned int)max_tx_rate) { 15280deb0bf7SJacob Keller ret = ice_set_max_bw_limit(vsi, (u64)max_tx_rate * 1000); 15290deb0bf7SJacob Keller if (ret) { 15300deb0bf7SJacob Keller dev_err(dev, "Unable to set max-tx-rate for VF %d\n", 15310deb0bf7SJacob Keller vf->vf_id); 15320deb0bf7SJacob Keller goto out_put_vf; 15330deb0bf7SJacob Keller } 15340deb0bf7SJacob Keller 15350deb0bf7SJacob Keller vf->max_tx_rate = max_tx_rate; 15360deb0bf7SJacob Keller } 15370deb0bf7SJacob Keller 15380deb0bf7SJacob Keller out_put_vf: 15390deb0bf7SJacob Keller ice_put_vf(vf); 15400deb0bf7SJacob Keller return ret; 15410deb0bf7SJacob Keller } 15420deb0bf7SJacob Keller 15430deb0bf7SJacob Keller /** 15440deb0bf7SJacob Keller * ice_get_vf_stats - populate some stats for the VF 15450deb0bf7SJacob Keller * @netdev: the netdev of the PF 15460deb0bf7SJacob Keller * @vf_id: the host OS identifier (0-255) 15470deb0bf7SJacob Keller * @vf_stats: pointer to the OS memory to be initialized 15480deb0bf7SJacob Keller */ 15490deb0bf7SJacob Keller int ice_get_vf_stats(struct net_device *netdev, int vf_id, 15500deb0bf7SJacob Keller struct ifla_vf_stats *vf_stats) 15510deb0bf7SJacob Keller { 15520deb0bf7SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 15530deb0bf7SJacob Keller struct ice_eth_stats *stats; 15540deb0bf7SJacob Keller struct ice_vsi *vsi; 15550deb0bf7SJacob Keller struct ice_vf *vf; 15560deb0bf7SJacob Keller int ret; 15570deb0bf7SJacob Keller 15580deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 15590deb0bf7SJacob Keller if (!vf) 15600deb0bf7SJacob Keller return -EINVAL; 15610deb0bf7SJacob Keller 15620deb0bf7SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 15630deb0bf7SJacob Keller if (ret) 15640deb0bf7SJacob Keller goto out_put_vf; 15650deb0bf7SJacob Keller 15660deb0bf7SJacob Keller vsi = ice_get_vf_vsi(vf); 15670deb0bf7SJacob Keller if (!vsi) { 15680deb0bf7SJacob Keller ret = -EINVAL; 15690deb0bf7SJacob Keller goto out_put_vf; 15700deb0bf7SJacob Keller } 15710deb0bf7SJacob Keller 15720deb0bf7SJacob Keller ice_update_eth_stats(vsi); 15730deb0bf7SJacob Keller stats = &vsi->eth_stats; 15740deb0bf7SJacob Keller 15750deb0bf7SJacob Keller memset(vf_stats, 0, sizeof(*vf_stats)); 15760deb0bf7SJacob Keller 15770deb0bf7SJacob Keller vf_stats->rx_packets = stats->rx_unicast + stats->rx_broadcast + 15780deb0bf7SJacob Keller stats->rx_multicast; 15790deb0bf7SJacob Keller vf_stats->tx_packets = stats->tx_unicast + stats->tx_broadcast + 15800deb0bf7SJacob Keller stats->tx_multicast; 15810deb0bf7SJacob Keller vf_stats->rx_bytes = stats->rx_bytes; 15820deb0bf7SJacob Keller vf_stats->tx_bytes = stats->tx_bytes; 15830deb0bf7SJacob Keller vf_stats->broadcast = stats->rx_broadcast; 15840deb0bf7SJacob Keller vf_stats->multicast = stats->rx_multicast; 15850deb0bf7SJacob Keller vf_stats->rx_dropped = stats->rx_discards; 15860deb0bf7SJacob Keller vf_stats->tx_dropped = stats->tx_discards; 15870deb0bf7SJacob Keller 15880deb0bf7SJacob Keller out_put_vf: 15890deb0bf7SJacob Keller ice_put_vf(vf); 15900deb0bf7SJacob Keller return ret; 15910deb0bf7SJacob Keller } 15920deb0bf7SJacob Keller 15930deb0bf7SJacob Keller /** 1594346f7aa3SJacob Keller * ice_is_supported_port_vlan_proto - make sure the vlan_proto is supported 1595346f7aa3SJacob Keller * @hw: hardware structure used to check the VLAN mode 1596346f7aa3SJacob Keller * @vlan_proto: VLAN TPID being checked 1597346f7aa3SJacob Keller * 1598346f7aa3SJacob Keller * If the device is configured in Double VLAN Mode (DVM), then both ETH_P_8021Q 1599346f7aa3SJacob Keller * and ETH_P_8021AD are supported. If the device is configured in Single VLAN 1600346f7aa3SJacob Keller * Mode (SVM), then only ETH_P_8021Q is supported. 1601346f7aa3SJacob Keller */ 1602346f7aa3SJacob Keller static bool 1603346f7aa3SJacob Keller ice_is_supported_port_vlan_proto(struct ice_hw *hw, u16 vlan_proto) 1604346f7aa3SJacob Keller { 1605346f7aa3SJacob Keller bool is_supported = false; 1606346f7aa3SJacob Keller 1607346f7aa3SJacob Keller switch (vlan_proto) { 1608346f7aa3SJacob Keller case ETH_P_8021Q: 1609346f7aa3SJacob Keller is_supported = true; 1610346f7aa3SJacob Keller break; 1611346f7aa3SJacob Keller case ETH_P_8021AD: 1612346f7aa3SJacob Keller if (ice_is_dvm_ena(hw)) 1613346f7aa3SJacob Keller is_supported = true; 1614346f7aa3SJacob Keller break; 1615346f7aa3SJacob Keller } 1616346f7aa3SJacob Keller 1617346f7aa3SJacob Keller return is_supported; 1618346f7aa3SJacob Keller } 1619346f7aa3SJacob Keller 1620346f7aa3SJacob Keller /** 1621346f7aa3SJacob Keller * ice_set_vf_port_vlan 1622346f7aa3SJacob Keller * @netdev: network interface device structure 1623346f7aa3SJacob Keller * @vf_id: VF identifier 1624346f7aa3SJacob Keller * @vlan_id: VLAN ID being set 1625346f7aa3SJacob Keller * @qos: priority setting 1626346f7aa3SJacob Keller * @vlan_proto: VLAN protocol 1627346f7aa3SJacob Keller * 1628346f7aa3SJacob Keller * program VF Port VLAN ID and/or QoS 1629346f7aa3SJacob Keller */ 1630346f7aa3SJacob Keller int 1631346f7aa3SJacob Keller ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, 1632346f7aa3SJacob Keller __be16 vlan_proto) 1633346f7aa3SJacob Keller { 1634346f7aa3SJacob Keller struct ice_pf *pf = ice_netdev_to_pf(netdev); 1635346f7aa3SJacob Keller u16 local_vlan_proto = ntohs(vlan_proto); 1636346f7aa3SJacob Keller struct device *dev; 1637346f7aa3SJacob Keller struct ice_vf *vf; 1638346f7aa3SJacob Keller int ret; 1639346f7aa3SJacob Keller 1640346f7aa3SJacob Keller dev = ice_pf_to_dev(pf); 1641346f7aa3SJacob Keller 1642346f7aa3SJacob Keller if (vlan_id >= VLAN_N_VID || qos > 7) { 1643346f7aa3SJacob Keller dev_err(dev, "Invalid Port VLAN parameters for VF %d, ID %d, QoS %d\n", 1644346f7aa3SJacob Keller vf_id, vlan_id, qos); 1645346f7aa3SJacob Keller return -EINVAL; 1646346f7aa3SJacob Keller } 1647346f7aa3SJacob Keller 1648346f7aa3SJacob Keller if (!ice_is_supported_port_vlan_proto(&pf->hw, local_vlan_proto)) { 1649346f7aa3SJacob Keller dev_err(dev, "VF VLAN protocol 0x%04x is not supported\n", 1650346f7aa3SJacob Keller local_vlan_proto); 1651346f7aa3SJacob Keller return -EPROTONOSUPPORT; 1652346f7aa3SJacob Keller } 1653346f7aa3SJacob Keller 1654346f7aa3SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 1655346f7aa3SJacob Keller if (!vf) 1656346f7aa3SJacob Keller return -EINVAL; 1657346f7aa3SJacob Keller 1658346f7aa3SJacob Keller ret = ice_check_vf_ready_for_cfg(vf); 1659346f7aa3SJacob Keller if (ret) 1660346f7aa3SJacob Keller goto out_put_vf; 1661346f7aa3SJacob Keller 1662346f7aa3SJacob Keller if (ice_vf_get_port_vlan_prio(vf) == qos && 1663346f7aa3SJacob Keller ice_vf_get_port_vlan_tpid(vf) == local_vlan_proto && 1664346f7aa3SJacob Keller ice_vf_get_port_vlan_id(vf) == vlan_id) { 1665346f7aa3SJacob Keller /* duplicate request, so just return success */ 1666346f7aa3SJacob Keller dev_dbg(dev, "Duplicate port VLAN %u, QoS %u, TPID 0x%04x request\n", 1667346f7aa3SJacob Keller vlan_id, qos, local_vlan_proto); 1668346f7aa3SJacob Keller ret = 0; 1669346f7aa3SJacob Keller goto out_put_vf; 1670346f7aa3SJacob Keller } 1671346f7aa3SJacob Keller 1672346f7aa3SJacob Keller mutex_lock(&vf->cfg_lock); 1673346f7aa3SJacob Keller 1674346f7aa3SJacob Keller vf->port_vlan_info = ICE_VLAN(local_vlan_proto, vlan_id, qos); 1675346f7aa3SJacob Keller if (ice_vf_is_port_vlan_ena(vf)) 1676346f7aa3SJacob Keller dev_info(dev, "Setting VLAN %u, QoS %u, TPID 0x%04x on VF %d\n", 1677346f7aa3SJacob Keller vlan_id, qos, local_vlan_proto, vf_id); 1678346f7aa3SJacob Keller else 1679346f7aa3SJacob Keller dev_info(dev, "Clearing port VLAN on VF %d\n", vf_id); 1680346f7aa3SJacob Keller 16819dbb33daSJacob Keller ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); 1682346f7aa3SJacob Keller mutex_unlock(&vf->cfg_lock); 1683346f7aa3SJacob Keller 1684346f7aa3SJacob Keller out_put_vf: 1685346f7aa3SJacob Keller ice_put_vf(vf); 1686346f7aa3SJacob Keller return ret; 1687346f7aa3SJacob Keller } 1688346f7aa3SJacob Keller 1689346f7aa3SJacob Keller /** 16900deb0bf7SJacob Keller * ice_print_vf_rx_mdd_event - print VF Rx malicious driver detect event 16910deb0bf7SJacob Keller * @vf: pointer to the VF structure 16920deb0bf7SJacob Keller */ 16930deb0bf7SJacob Keller void ice_print_vf_rx_mdd_event(struct ice_vf *vf) 16940deb0bf7SJacob Keller { 16950deb0bf7SJacob Keller struct ice_pf *pf = vf->pf; 16960deb0bf7SJacob Keller struct device *dev; 16970deb0bf7SJacob Keller 16980deb0bf7SJacob Keller dev = ice_pf_to_dev(pf); 16990deb0bf7SJacob Keller 17000deb0bf7SJacob Keller dev_info(dev, "%d Rx Malicious Driver Detection events detected on PF %d VF %d MAC %pM. mdd-auto-reset-vfs=%s\n", 17010deb0bf7SJacob Keller vf->mdd_rx_events.count, pf->hw.pf_id, vf->vf_id, 1702e0645311SJacob Keller vf->dev_lan_addr, 17030deb0bf7SJacob Keller test_bit(ICE_FLAG_MDD_AUTO_RESET_VF, pf->flags) 17040deb0bf7SJacob Keller ? "on" : "off"); 17050deb0bf7SJacob Keller } 17060deb0bf7SJacob Keller 17070deb0bf7SJacob Keller /** 17080deb0bf7SJacob Keller * ice_print_vfs_mdd_events - print VFs malicious driver detect event 17090deb0bf7SJacob Keller * @pf: pointer to the PF structure 17100deb0bf7SJacob Keller * 17110deb0bf7SJacob Keller * Called from ice_handle_mdd_event to rate limit and print VFs MDD events. 17120deb0bf7SJacob Keller */ 17130deb0bf7SJacob Keller void ice_print_vfs_mdd_events(struct ice_pf *pf) 17140deb0bf7SJacob Keller { 17150deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 17160deb0bf7SJacob Keller struct ice_hw *hw = &pf->hw; 17170deb0bf7SJacob Keller struct ice_vf *vf; 17180deb0bf7SJacob Keller unsigned int bkt; 17190deb0bf7SJacob Keller 17200deb0bf7SJacob Keller /* check that there are pending MDD events to print */ 17210deb0bf7SJacob Keller if (!test_and_clear_bit(ICE_MDD_VF_PRINT_PENDING, pf->state)) 17220deb0bf7SJacob Keller return; 17230deb0bf7SJacob Keller 17240deb0bf7SJacob Keller /* VF MDD event logs are rate limited to one second intervals */ 17250deb0bf7SJacob Keller if (time_is_after_jiffies(pf->vfs.last_printed_mdd_jiffies + HZ * 1)) 17260deb0bf7SJacob Keller return; 17270deb0bf7SJacob Keller 17280deb0bf7SJacob Keller pf->vfs.last_printed_mdd_jiffies = jiffies; 17290deb0bf7SJacob Keller 17300deb0bf7SJacob Keller mutex_lock(&pf->vfs.table_lock); 17310deb0bf7SJacob Keller ice_for_each_vf(pf, bkt, vf) { 17320deb0bf7SJacob Keller /* only print Rx MDD event message if there are new events */ 17330deb0bf7SJacob Keller if (vf->mdd_rx_events.count != vf->mdd_rx_events.last_printed) { 17340deb0bf7SJacob Keller vf->mdd_rx_events.last_printed = 17350deb0bf7SJacob Keller vf->mdd_rx_events.count; 17360deb0bf7SJacob Keller ice_print_vf_rx_mdd_event(vf); 17370deb0bf7SJacob Keller } 17380deb0bf7SJacob Keller 17390deb0bf7SJacob Keller /* only print Tx MDD event message if there are new events */ 17400deb0bf7SJacob Keller if (vf->mdd_tx_events.count != vf->mdd_tx_events.last_printed) { 17410deb0bf7SJacob Keller vf->mdd_tx_events.last_printed = 17420deb0bf7SJacob Keller vf->mdd_tx_events.count; 17430deb0bf7SJacob Keller 17440deb0bf7SJacob Keller dev_info(dev, "%d Tx Malicious Driver Detection events detected on PF %d VF %d MAC %pM.\n", 17450deb0bf7SJacob Keller vf->mdd_tx_events.count, hw->pf_id, vf->vf_id, 1746e0645311SJacob Keller vf->dev_lan_addr); 17470deb0bf7SJacob Keller } 17480deb0bf7SJacob Keller } 17490deb0bf7SJacob Keller mutex_unlock(&pf->vfs.table_lock); 17500deb0bf7SJacob Keller } 17510deb0bf7SJacob Keller 17520deb0bf7SJacob Keller /** 17530deb0bf7SJacob Keller * ice_restore_all_vfs_msi_state - restore VF MSI state after PF FLR 17540deb0bf7SJacob Keller * @pdev: pointer to a pci_dev structure 17550deb0bf7SJacob Keller * 17560deb0bf7SJacob Keller * Called when recovering from a PF FLR to restore interrupt capability to 17570deb0bf7SJacob Keller * the VFs. 17580deb0bf7SJacob Keller */ 17590deb0bf7SJacob Keller void ice_restore_all_vfs_msi_state(struct pci_dev *pdev) 17600deb0bf7SJacob Keller { 17610deb0bf7SJacob Keller u16 vf_id; 17620deb0bf7SJacob Keller int pos; 17630deb0bf7SJacob Keller 17640deb0bf7SJacob Keller if (!pci_num_vf(pdev)) 17650deb0bf7SJacob Keller return; 17660deb0bf7SJacob Keller 17670deb0bf7SJacob Keller pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); 17680deb0bf7SJacob Keller if (pos) { 17690deb0bf7SJacob Keller struct pci_dev *vfdev; 17700deb0bf7SJacob Keller 17710deb0bf7SJacob Keller pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, 17720deb0bf7SJacob Keller &vf_id); 17730deb0bf7SJacob Keller vfdev = pci_get_device(pdev->vendor, vf_id, NULL); 17740deb0bf7SJacob Keller while (vfdev) { 17750deb0bf7SJacob Keller if (vfdev->is_virtfn && vfdev->physfn == pdev) 17760deb0bf7SJacob Keller pci_restore_msi_state(vfdev); 17770deb0bf7SJacob Keller vfdev = pci_get_device(pdev->vendor, vf_id, 17780deb0bf7SJacob Keller vfdev); 17790deb0bf7SJacob Keller } 17800deb0bf7SJacob Keller } 17810deb0bf7SJacob Keller } 17820deb0bf7SJacob Keller 17830deb0bf7SJacob Keller /** 17840deb0bf7SJacob Keller * ice_is_malicious_vf - helper function to detect a malicious VF 17850deb0bf7SJacob Keller * @pf: ptr to struct ice_pf 17860deb0bf7SJacob Keller * @event: pointer to the AQ event 17870deb0bf7SJacob Keller * @num_msg_proc: the number of messages processed so far 17880deb0bf7SJacob Keller * @num_msg_pending: the number of messages peinding in admin queue 17890deb0bf7SJacob Keller */ 17900deb0bf7SJacob Keller bool 17910deb0bf7SJacob Keller ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event, 17920deb0bf7SJacob Keller u16 num_msg_proc, u16 num_msg_pending) 17930deb0bf7SJacob Keller { 17940deb0bf7SJacob Keller s16 vf_id = le16_to_cpu(event->desc.retval); 17950deb0bf7SJacob Keller struct device *dev = ice_pf_to_dev(pf); 17960deb0bf7SJacob Keller struct ice_mbx_data mbxdata; 17970deb0bf7SJacob Keller bool malvf = false; 17980deb0bf7SJacob Keller struct ice_vf *vf; 17990deb0bf7SJacob Keller int status; 18000deb0bf7SJacob Keller 18010deb0bf7SJacob Keller vf = ice_get_vf_by_id(pf, vf_id); 18020deb0bf7SJacob Keller if (!vf) 18030deb0bf7SJacob Keller return false; 18040deb0bf7SJacob Keller 18050deb0bf7SJacob Keller if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) 18060deb0bf7SJacob Keller goto out_put_vf; 18070deb0bf7SJacob Keller 18080deb0bf7SJacob Keller mbxdata.num_msg_proc = num_msg_proc; 18090deb0bf7SJacob Keller mbxdata.num_pending_arq = num_msg_pending; 18100deb0bf7SJacob Keller mbxdata.max_num_msgs_mbx = pf->hw.mailboxq.num_rq_entries; 18110deb0bf7SJacob Keller #define ICE_MBX_OVERFLOW_WATERMARK 64 18120deb0bf7SJacob Keller mbxdata.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK; 18130deb0bf7SJacob Keller 18140deb0bf7SJacob Keller /* check to see if we have a malicious VF */ 18158cd8a6b1SJacob Keller status = ice_mbx_vf_state_handler(&pf->hw, &mbxdata, &vf->mbx_info, &malvf); 18160deb0bf7SJacob Keller if (status) 18170deb0bf7SJacob Keller goto out_put_vf; 18180deb0bf7SJacob Keller 18190deb0bf7SJacob Keller if (malvf) { 18200deb0bf7SJacob Keller bool report_vf = false; 18210deb0bf7SJacob Keller 18220deb0bf7SJacob Keller /* if the VF is malicious and we haven't let the user 18230deb0bf7SJacob Keller * know about it, then let them know now 18240deb0bf7SJacob Keller */ 1825e4eaf893SJacob Keller status = ice_mbx_report_malvf(&pf->hw, &vf->mbx_info, 18260deb0bf7SJacob Keller &report_vf); 18270deb0bf7SJacob Keller if (status) 18280deb0bf7SJacob Keller dev_dbg(dev, "Error reporting malicious VF\n"); 18290deb0bf7SJacob Keller 18300deb0bf7SJacob Keller if (report_vf) { 18310deb0bf7SJacob Keller struct ice_vsi *pf_vsi = ice_get_main_vsi(pf); 18320deb0bf7SJacob Keller 18330deb0bf7SJacob Keller if (pf_vsi) 18340deb0bf7SJacob Keller dev_warn(dev, "VF MAC %pM on PF MAC %pM is generating asynchronous messages and may be overflowing the PF message queue. Please see the Adapter User Guide for more information\n", 1835e0645311SJacob Keller &vf->dev_lan_addr[0], 18360deb0bf7SJacob Keller pf_vsi->netdev->dev_addr); 18370deb0bf7SJacob Keller } 18380deb0bf7SJacob Keller } 18390deb0bf7SJacob Keller 18400deb0bf7SJacob Keller out_put_vf: 18410deb0bf7SJacob Keller ice_put_vf(vf); 18420deb0bf7SJacob Keller return malvf; 18430deb0bf7SJacob Keller } 1844