178a9b3c4SPieter Jansen van Vuuren // SPDX-License-Identifier: GPL-2.0-only
278a9b3c4SPieter Jansen van Vuuren /****************************************************************************
378a9b3c4SPieter Jansen van Vuuren * Driver for Solarflare network controllers and boards
478a9b3c4SPieter Jansen van Vuuren * Copyright 2019 Solarflare Communications Inc.
578a9b3c4SPieter Jansen van Vuuren * Copyright 2020-2022 Xilinx Inc.
678a9b3c4SPieter Jansen van Vuuren *
778a9b3c4SPieter Jansen van Vuuren * This program is free software; you can redistribute it and/or modify it
878a9b3c4SPieter Jansen van Vuuren * under the terms of the GNU General Public License version 2 as published
978a9b3c4SPieter Jansen van Vuuren * by the Free Software Foundation, incorporated herein by reference.
1078a9b3c4SPieter Jansen van Vuuren */
1178a9b3c4SPieter Jansen van Vuuren
1278a9b3c4SPieter Jansen van Vuuren #include "ef100_sriov.h"
1378a9b3c4SPieter Jansen van Vuuren #include "ef100_nic.h"
14*08135eecSEdward Cree #include "ef100_rep.h"
1578a9b3c4SPieter Jansen van Vuuren
efx_ef100_pci_sriov_enable(struct efx_nic * efx,int num_vfs)1678a9b3c4SPieter Jansen van Vuuren static int efx_ef100_pci_sriov_enable(struct efx_nic *efx, int num_vfs)
1778a9b3c4SPieter Jansen van Vuuren {
18*08135eecSEdward Cree struct ef100_nic_data *nic_data = efx->nic_data;
1978a9b3c4SPieter Jansen van Vuuren struct pci_dev *dev = efx->pci_dev;
20*08135eecSEdward Cree struct efx_rep *efv, *next;
21*08135eecSEdward Cree int rc, i;
2278a9b3c4SPieter Jansen van Vuuren
2378a9b3c4SPieter Jansen van Vuuren efx->vf_count = num_vfs;
2478a9b3c4SPieter Jansen van Vuuren rc = pci_enable_sriov(dev, num_vfs);
2578a9b3c4SPieter Jansen van Vuuren if (rc)
26*08135eecSEdward Cree goto fail1;
2778a9b3c4SPieter Jansen van Vuuren
28*08135eecSEdward Cree if (!nic_data->grp_mae)
2978a9b3c4SPieter Jansen van Vuuren return 0;
3078a9b3c4SPieter Jansen van Vuuren
31*08135eecSEdward Cree for (i = 0; i < num_vfs; i++) {
32*08135eecSEdward Cree rc = efx_ef100_vfrep_create(efx, i);
33*08135eecSEdward Cree if (rc)
34*08135eecSEdward Cree goto fail2;
35*08135eecSEdward Cree }
36*08135eecSEdward Cree return 0;
37*08135eecSEdward Cree
38*08135eecSEdward Cree fail2:
39*08135eecSEdward Cree list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
40*08135eecSEdward Cree efx_ef100_vfrep_destroy(efx, efv);
41*08135eecSEdward Cree pci_disable_sriov(dev);
42*08135eecSEdward Cree fail1:
4378a9b3c4SPieter Jansen van Vuuren netif_err(efx, probe, efx->net_dev, "Failed to enable SRIOV VFs\n");
4478a9b3c4SPieter Jansen van Vuuren efx->vf_count = 0;
4578a9b3c4SPieter Jansen van Vuuren return rc;
4678a9b3c4SPieter Jansen van Vuuren }
4778a9b3c4SPieter Jansen van Vuuren
efx_ef100_pci_sriov_disable(struct efx_nic * efx,bool force)48*08135eecSEdward Cree int efx_ef100_pci_sriov_disable(struct efx_nic *efx, bool force)
4978a9b3c4SPieter Jansen van Vuuren {
5078a9b3c4SPieter Jansen van Vuuren struct pci_dev *dev = efx->pci_dev;
5178a9b3c4SPieter Jansen van Vuuren unsigned int vfs_assigned;
5278a9b3c4SPieter Jansen van Vuuren
5378a9b3c4SPieter Jansen van Vuuren vfs_assigned = pci_vfs_assigned(dev);
54*08135eecSEdward Cree if (vfs_assigned && !force) {
5578a9b3c4SPieter Jansen van Vuuren netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
5678a9b3c4SPieter Jansen van Vuuren "please detach them before disabling SR-IOV\n");
5778a9b3c4SPieter Jansen van Vuuren return -EBUSY;
5878a9b3c4SPieter Jansen van Vuuren }
5978a9b3c4SPieter Jansen van Vuuren
60*08135eecSEdward Cree efx_ef100_fini_vfreps(efx);
61*08135eecSEdward Cree if (!vfs_assigned)
6278a9b3c4SPieter Jansen van Vuuren pci_disable_sriov(dev);
6378a9b3c4SPieter Jansen van Vuuren return 0;
6478a9b3c4SPieter Jansen van Vuuren }
6578a9b3c4SPieter Jansen van Vuuren
efx_ef100_sriov_configure(struct efx_nic * efx,int num_vfs)6678a9b3c4SPieter Jansen van Vuuren int efx_ef100_sriov_configure(struct efx_nic *efx, int num_vfs)
6778a9b3c4SPieter Jansen van Vuuren {
6878a9b3c4SPieter Jansen van Vuuren if (num_vfs == 0)
69*08135eecSEdward Cree return efx_ef100_pci_sriov_disable(efx, false);
7078a9b3c4SPieter Jansen van Vuuren else
7178a9b3c4SPieter Jansen van Vuuren return efx_ef100_pci_sriov_enable(efx, num_vfs);
7278a9b3c4SPieter Jansen van Vuuren }
73