iov.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * drivers/pci/iov.c
  3. *
  4. * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
  5. *
  6. * PCI Express I/O Virtualization (IOV) support.
  7. * Single Root IOV 1.0
  8. */
  9. #include <linux/pci.h>
  10. #include <linux/mutex.h>
  11. #include <linux/string.h>
  12. #include <linux/delay.h>
  13. #include "pci.h"
  14. static inline u8 virtfn_bus(struct pci_dev *dev, int id)
  15. {
  16. return dev->bus->number + ((dev->devfn + dev->sriov->offset +
  17. dev->sriov->stride * id) >> 8);
  18. }
  19. static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
  20. {
  21. return (dev->devfn + dev->sriov->offset +
  22. dev->sriov->stride * id) & 0xff;
  23. }
  24. static int sriov_init(struct pci_dev *dev, int pos)
  25. {
  26. int i;
  27. int rc;
  28. int nres;
  29. u32 pgsz;
  30. u16 ctrl, total, offset, stride;
  31. struct pci_sriov *iov;
  32. struct resource *res;
  33. struct pci_dev *pdev;
  34. if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
  35. dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
  36. return -ENODEV;
  37. pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
  38. if (ctrl & PCI_SRIOV_CTRL_VFE) {
  39. pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0);
  40. ssleep(1);
  41. }
  42. pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &total);
  43. if (!total)
  44. return 0;
  45. ctrl = 0;
  46. list_for_each_entry(pdev, &dev->bus->devices, bus_list)
  47. if (pdev->is_physfn)
  48. goto found;
  49. pdev = NULL;
  50. if (pci_ari_enabled(dev->bus))
  51. ctrl |= PCI_SRIOV_CTRL_ARI;
  52. found:
  53. pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
  54. pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
  55. pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
  56. pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
  57. if (!offset || (total > 1 && !stride))
  58. return -EIO;
  59. pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &pgsz);
  60. i = PAGE_SHIFT > 12 ? PAGE_SHIFT - 12 : 0;
  61. pgsz &= ~((1 << i) - 1);
  62. if (!pgsz)
  63. return -EIO;
  64. pgsz &= ~(pgsz - 1);
  65. pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
  66. nres = 0;
  67. for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
  68. res = dev->resource + PCI_IOV_RESOURCES + i;
  69. i += __pci_read_base(dev, pci_bar_unknown, res,
  70. pos + PCI_SRIOV_BAR + i * 4);
  71. if (!res->flags)
  72. continue;
  73. if (resource_size(res) & (PAGE_SIZE - 1)) {
  74. rc = -EIO;
  75. goto failed;
  76. }
  77. res->end = res->start + resource_size(res) * total - 1;
  78. nres++;
  79. }
  80. iov = kzalloc(sizeof(*iov), GFP_KERNEL);
  81. if (!iov) {
  82. rc = -ENOMEM;
  83. goto failed;
  84. }
  85. iov->pos = pos;
  86. iov->nres = nres;
  87. iov->ctrl = ctrl;
  88. iov->total = total;
  89. iov->offset = offset;
  90. iov->stride = stride;
  91. iov->pgsz = pgsz;
  92. iov->self = dev;
  93. pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
  94. pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
  95. if (pdev)
  96. iov->dev = pci_dev_get(pdev);
  97. else {
  98. iov->dev = dev;
  99. mutex_init(&iov->lock);
  100. }
  101. dev->sriov = iov;
  102. dev->is_physfn = 1;
  103. return 0;
  104. failed:
  105. for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
  106. res = dev->resource + PCI_IOV_RESOURCES + i;
  107. res->flags = 0;
  108. }
  109. return rc;
  110. }
  111. static void sriov_release(struct pci_dev *dev)
  112. {
  113. if (dev == dev->sriov->dev)
  114. mutex_destroy(&dev->sriov->lock);
  115. else
  116. pci_dev_put(dev->sriov->dev);
  117. kfree(dev->sriov);
  118. dev->sriov = NULL;
  119. }
  120. static void sriov_restore_state(struct pci_dev *dev)
  121. {
  122. int i;
  123. u16 ctrl;
  124. struct pci_sriov *iov = dev->sriov;
  125. pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &ctrl);
  126. if (ctrl & PCI_SRIOV_CTRL_VFE)
  127. return;
  128. for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
  129. pci_update_resource(dev, i);
  130. pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
  131. pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
  132. if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
  133. msleep(100);
  134. }
  135. /**
  136. * pci_iov_init - initialize the IOV capability
  137. * @dev: the PCI device
  138. *
  139. * Returns 0 on success, or negative on failure.
  140. */
  141. int pci_iov_init(struct pci_dev *dev)
  142. {
  143. int pos;
  144. if (!dev->is_pcie)
  145. return -ENODEV;
  146. pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
  147. if (pos)
  148. return sriov_init(dev, pos);
  149. return -ENODEV;
  150. }
  151. /**
  152. * pci_iov_release - release resources used by the IOV capability
  153. * @dev: the PCI device
  154. */
  155. void pci_iov_release(struct pci_dev *dev)
  156. {
  157. if (dev->is_physfn)
  158. sriov_release(dev);
  159. }
  160. /**
  161. * pci_iov_resource_bar - get position of the SR-IOV BAR
  162. * @dev: the PCI device
  163. * @resno: the resource number
  164. * @type: the BAR type to be filled in
  165. *
  166. * Returns position of the BAR encapsulated in the SR-IOV capability.
  167. */
  168. int pci_iov_resource_bar(struct pci_dev *dev, int resno,
  169. enum pci_bar_type *type)
  170. {
  171. if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
  172. return 0;
  173. BUG_ON(!dev->is_physfn);
  174. *type = pci_bar_unknown;
  175. return dev->sriov->pos + PCI_SRIOV_BAR +
  176. 4 * (resno - PCI_IOV_RESOURCES);
  177. }
  178. /**
  179. * pci_restore_iov_state - restore the state of the IOV capability
  180. * @dev: the PCI device
  181. */
  182. void pci_restore_iov_state(struct pci_dev *dev)
  183. {
  184. if (dev->is_physfn)
  185. sriov_restore_state(dev);
  186. }
  187. /**
  188. * pci_iov_bus_range - find bus range used by Virtual Function
  189. * @bus: the PCI bus
  190. *
  191. * Returns max number of buses (exclude current one) used by Virtual
  192. * Functions.
  193. */
  194. int pci_iov_bus_range(struct pci_bus *bus)
  195. {
  196. int max = 0;
  197. u8 busnr;
  198. struct pci_dev *dev;
  199. list_for_each_entry(dev, &bus->devices, bus_list) {
  200. if (!dev->is_physfn)
  201. continue;
  202. busnr = virtfn_bus(dev, dev->sriov->total - 1);
  203. if (busnr > max)
  204. max = busnr;
  205. }
  206. return max ? max - bus->number : 0;
  207. }