pci_iov.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright IBM Corp. 2020
  4. *
  5. * Author(s):
  6. * Niklas Schnelle <[email protected]>
  7. *
  8. */
  9. #define KMSG_COMPONENT "zpci"
  10. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  11. #include <linux/kernel.h>
  12. #include <linux/pci.h>
  13. #include "pci_iov.h"
  14. static struct resource iov_res = {
  15. .name = "PCI IOV res",
  16. .start = 0,
  17. .end = -1,
  18. .flags = IORESOURCE_MEM,
  19. };
  20. void zpci_iov_map_resources(struct pci_dev *pdev)
  21. {
  22. resource_size_t len;
  23. int i;
  24. for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
  25. int bar = i + PCI_IOV_RESOURCES;
  26. len = pci_resource_len(pdev, bar);
  27. if (!len)
  28. continue;
  29. pdev->resource[bar].parent = &iov_res;
  30. }
  31. }
  32. void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn)
  33. {
  34. pci_lock_rescan_remove();
  35. /* Linux' vfid's start at 0 vfn at 1 */
  36. pci_iov_remove_virtfn(pdev->physfn, vfn - 1);
  37. pci_unlock_rescan_remove();
  38. }
  39. static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, int vfid)
  40. {
  41. int rc;
  42. rc = pci_iov_sysfs_link(pdev, virtfn, vfid);
  43. if (rc)
  44. return rc;
  45. virtfn->is_virtfn = 1;
  46. virtfn->multifunction = 0;
  47. virtfn->physfn = pci_dev_get(pdev);
  48. return 0;
  49. }
  50. int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
  51. {
  52. int i, cand_devfn;
  53. struct zpci_dev *zdev;
  54. struct pci_dev *pdev;
  55. int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/
  56. int rc = 0;
  57. if (!zbus->multifunction)
  58. return 0;
  59. /* If the parent PF for the given VF is also configured in the
  60. * instance, it must be on the same zbus.
  61. * We can then identify the parent PF by checking what
  62. * devfn the VF would have if it belonged to that PF using the PF's
  63. * stride and offset. Only if this candidate devfn matches the
  64. * actual devfn will we link both functions.
  65. */
  66. for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
  67. zdev = zbus->function[i];
  68. if (zdev && zdev->is_physfn) {
  69. pdev = pci_get_slot(zbus->bus, zdev->devfn);
  70. if (!pdev)
  71. continue;
  72. cand_devfn = pci_iov_virtfn_devfn(pdev, vfid);
  73. if (cand_devfn == virtfn->devfn) {
  74. rc = zpci_iov_link_virtfn(pdev, virtfn, vfid);
  75. /* balance pci_get_slot() */
  76. pci_dev_put(pdev);
  77. break;
  78. }
  79. /* balance pci_get_slot() */
  80. pci_dev_put(pdev);
  81. }
  82. }
  83. return rc;
  84. }