xref: /openbmc/linux/drivers/net/ethernet/sfc/ef100_sriov.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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