ef100_sriov.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. #include "ef100_sriov.h"
  12. #include "ef100_nic.h"
  13. #include "ef100_rep.h"
  14. static int efx_ef100_pci_sriov_enable(struct efx_nic *efx, int num_vfs)
  15. {
  16. struct ef100_nic_data *nic_data = efx->nic_data;
  17. struct pci_dev *dev = efx->pci_dev;
  18. struct efx_rep *efv, *next;
  19. int rc, i;
  20. efx->vf_count = num_vfs;
  21. rc = pci_enable_sriov(dev, num_vfs);
  22. if (rc)
  23. goto fail1;
  24. if (!nic_data->grp_mae)
  25. return 0;
  26. for (i = 0; i < num_vfs; i++) {
  27. rc = efx_ef100_vfrep_create(efx, i);
  28. if (rc)
  29. goto fail2;
  30. }
  31. return 0;
  32. fail2:
  33. list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
  34. efx_ef100_vfrep_destroy(efx, efv);
  35. pci_disable_sriov(dev);
  36. fail1:
  37. netif_err(efx, probe, efx->net_dev, "Failed to enable SRIOV VFs\n");
  38. efx->vf_count = 0;
  39. return rc;
  40. }
  41. int efx_ef100_pci_sriov_disable(struct efx_nic *efx, bool force)
  42. {
  43. struct pci_dev *dev = efx->pci_dev;
  44. unsigned int vfs_assigned;
  45. vfs_assigned = pci_vfs_assigned(dev);
  46. if (vfs_assigned && !force) {
  47. netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
  48. "please detach them before disabling SR-IOV\n");
  49. return -EBUSY;
  50. }
  51. efx_ef100_fini_vfreps(efx);
  52. if (!vfs_assigned)
  53. pci_disable_sriov(dev);
  54. return 0;
  55. }
  56. int efx_ef100_sriov_configure(struct efx_nic *efx, int num_vfs)
  57. {
  58. if (num_vfs == 0)
  59. return efx_ef100_pci_sriov_disable(efx, false);
  60. else
  61. return efx_ef100_pci_sriov_enable(efx, num_vfs);
  62. }