1 // SPDX-License-Identifier: GPL-2.0-only 2 /**************************************************************************** 3 * Driver for Solarflare network controllers and boards 4 * Copyright 2019 Solarflare Communications Inc. 5 * Copyright 2020-2022 Xilinx Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published 9 * by the Free Software Foundation, incorporated herein by reference. 10 */ 11 12 #include "ef100_sriov.h" 13 #include "ef100_nic.h" 14 #include "ef100_rep.h" 15 16 static int efx_ef100_pci_sriov_enable(struct efx_nic *efx, int num_vfs) 17 { 18 struct ef100_nic_data *nic_data = efx->nic_data; 19 struct pci_dev *dev = efx->pci_dev; 20 struct efx_rep *efv, *next; 21 int rc, i; 22 23 efx->vf_count = num_vfs; 24 rc = pci_enable_sriov(dev, num_vfs); 25 if (rc) 26 goto fail1; 27 28 if (!nic_data->grp_mae) 29 return 0; 30 31 for (i = 0; i < num_vfs; i++) { 32 rc = efx_ef100_vfrep_create(efx, i); 33 if (rc) 34 goto fail2; 35 } 36 return 0; 37 38 fail2: 39 list_for_each_entry_safe(efv, next, &efx->vf_reps, list) 40 efx_ef100_vfrep_destroy(efx, efv); 41 pci_disable_sriov(dev); 42 fail1: 43 netif_err(efx, probe, efx->net_dev, "Failed to enable SRIOV VFs\n"); 44 efx->vf_count = 0; 45 return rc; 46 } 47 48 int efx_ef100_pci_sriov_disable(struct efx_nic *efx, bool force) 49 { 50 struct pci_dev *dev = efx->pci_dev; 51 unsigned int vfs_assigned; 52 53 vfs_assigned = pci_vfs_assigned(dev); 54 if (vfs_assigned && !force) { 55 netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; " 56 "please detach them before disabling SR-IOV\n"); 57 return -EBUSY; 58 } 59 60 efx_ef100_fini_vfreps(efx); 61 if (!vfs_assigned) 62 pci_disable_sriov(dev); 63 return 0; 64 } 65 66 int efx_ef100_sriov_configure(struct efx_nic *efx, int num_vfs) 67 { 68 if (num_vfs == 0) 69 return efx_ef100_pci_sriov_disable(efx, false); 70 else 71 return efx_ef100_pci_sriov_enable(efx, num_vfs); 72 } 73