nitrox_sriov.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/pci.h>
  3. #include <linux/delay.h>
  4. #include "nitrox_dev.h"
  5. #include "nitrox_hal.h"
  6. #include "nitrox_common.h"
  7. #include "nitrox_isr.h"
  8. static inline bool num_vfs_valid(int num_vfs)
  9. {
  10. bool valid = false;
  11. switch (num_vfs) {
  12. case 16:
  13. case 32:
  14. case 64:
  15. case 128:
  16. valid = true;
  17. break;
  18. }
  19. return valid;
  20. }
  21. static inline enum vf_mode num_vfs_to_mode(int num_vfs)
  22. {
  23. enum vf_mode mode = 0;
  24. switch (num_vfs) {
  25. case 0:
  26. mode = __NDEV_MODE_PF;
  27. break;
  28. case 16:
  29. mode = __NDEV_MODE_VF16;
  30. break;
  31. case 32:
  32. mode = __NDEV_MODE_VF32;
  33. break;
  34. case 64:
  35. mode = __NDEV_MODE_VF64;
  36. break;
  37. case 128:
  38. mode = __NDEV_MODE_VF128;
  39. break;
  40. }
  41. return mode;
  42. }
  43. static void pf_sriov_cleanup(struct nitrox_device *ndev)
  44. {
  45. /* PF has no queues in SR-IOV mode */
  46. atomic_set(&ndev->state, __NDEV_NOT_READY);
  47. /* unregister crypto algorithms */
  48. nitrox_crypto_unregister();
  49. /* cleanup PF resources */
  50. nitrox_unregister_interrupts(ndev);
  51. nitrox_common_sw_cleanup(ndev);
  52. }
  53. static int pf_sriov_init(struct nitrox_device *ndev)
  54. {
  55. int err;
  56. /* allocate resources for PF */
  57. err = nitrox_common_sw_init(ndev);
  58. if (err)
  59. return err;
  60. err = nitrox_register_interrupts(ndev);
  61. if (err) {
  62. nitrox_common_sw_cleanup(ndev);
  63. return err;
  64. }
  65. /* configure the packet queues */
  66. nitrox_config_pkt_input_rings(ndev);
  67. nitrox_config_pkt_solicit_ports(ndev);
  68. /* set device to ready state */
  69. atomic_set(&ndev->state, __NDEV_READY);
  70. /* register crypto algorithms */
  71. return nitrox_crypto_register();
  72. }
  73. static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
  74. {
  75. struct nitrox_device *ndev = pci_get_drvdata(pdev);
  76. int err;
  77. if (!num_vfs_valid(num_vfs)) {
  78. dev_err(DEV(ndev), "Invalid num_vfs %d\n", num_vfs);
  79. return -EINVAL;
  80. }
  81. if (pci_num_vf(pdev) == num_vfs)
  82. return num_vfs;
  83. err = pci_enable_sriov(pdev, num_vfs);
  84. if (err) {
  85. dev_err(DEV(ndev), "failed to enable PCI sriov %d\n", err);
  86. return err;
  87. }
  88. dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs);
  89. ndev->num_vfs = num_vfs;
  90. ndev->mode = num_vfs_to_mode(num_vfs);
  91. /* set bit in flags */
  92. set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
  93. /* cleanup PF resources */
  94. pf_sriov_cleanup(ndev);
  95. config_nps_core_vfcfg_mode(ndev, ndev->mode);
  96. return num_vfs;
  97. }
  98. static int nitrox_sriov_disable(struct pci_dev *pdev)
  99. {
  100. struct nitrox_device *ndev = pci_get_drvdata(pdev);
  101. if (!test_bit(__NDEV_SRIOV_BIT, &ndev->flags))
  102. return 0;
  103. if (pci_vfs_assigned(pdev)) {
  104. dev_warn(DEV(ndev), "VFs are attached to VM. Can't disable SR-IOV\n");
  105. return -EPERM;
  106. }
  107. pci_disable_sriov(pdev);
  108. /* clear bit in flags */
  109. clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
  110. ndev->num_vfs = 0;
  111. ndev->mode = __NDEV_MODE_PF;
  112. config_nps_core_vfcfg_mode(ndev, ndev->mode);
  113. return pf_sriov_init(ndev);
  114. }
  115. int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)
  116. {
  117. if (!num_vfs)
  118. return nitrox_sriov_disable(pdev);
  119. return nitrox_sriov_enable(pdev, num_vfs);
  120. }