11 #include <linux/pci.h>
12 #include <linux/slab.h>
14 #include <linux/export.h>
15 #include <linux/string.h>
20 #define VIRTFN_ID_LEN 16
24 return dev->
bus->number + ((dev->
devfn + dev->sriov->offset +
25 dev->sriov->stride *
id) >> 8);
28 static inline u8 virtfn_devfn(
struct pci_dev *
dev,
int id)
30 return (dev->
devfn + dev->sriov->offset +
31 dev->sriov->stride *
id) & 0xff;
61 static void virtfn_remove_bus(
struct pci_bus *bus,
int busnr)
71 if (list_empty(&child->
devices))
75 static int virtfn_add(
struct pci_dev *dev,
int id,
int reset)
90 virtfn->
bus = virtfn_add_bus(dev->
bus, virtfn_bus(dev,
id));
96 virtfn->
devfn = virtfn_devfn(dev,
id);
100 virtfn->
dev.parent = dev->
dev.parent;
103 res = dev->
resource + PCI_IOV_RESOURCES +
i;
106 virtfn->
resource[
i].name = pci_name(virtfn);
108 size = resource_size(res);
146 virtfn_remove_bus(dev->
bus, virtfn_bus(dev,
id));
152 static void virtfn_remove(
struct pci_dev *dev,
int id,
int reset)
181 if (virtfn->
dev.kobj.sd)
186 virtfn_remove_bus(dev->
bus, virtfn_bus(dev,
id));
192 static int sriov_migration(
struct pci_dev *dev)
225 virtfn_add(iov->
self, i, 1);
227 virtfn_remove(iov->
self, i, 1);
231 virtfn_add(iov->
self, i, 0);
272 static void sriov_disable_migration(
struct pci_dev *dev)
283 static int sriov_enable(
struct pci_dev *dev,
int nr_virtfn)
301 if (initial > iov->
total ||
305 if (nr_virtfn < 0 || nr_virtfn > iov->
total ||
312 if (!offset || (nr_virtfn > 1 && !stride))
317 bars |= (1 << (i + PCI_IOV_RESOURCES));
318 res = dev->
resource + PCI_IOV_RESOURCES +
i;
322 if (nres != iov->
nres) {
323 dev_err(&dev->
dev,
"not enough MMIO resources for SR-IOV\n");
330 if (virtfn_bus(dev, nr_virtfn - 1) > dev->
bus->busn_res.end) {
331 dev_err(&dev->
dev,
"SR-IOV: bus number out of range\n");
336 dev_err(&dev->
dev,
"SR-IOV: IOV BARS not allocated\n");
351 &pdev->
dev.kobj,
"dep_link");
363 if (nr_virtfn < initial)
366 for (i = 0; i <
initial; i++) {
367 rc = virtfn_add(dev, i, 0);
373 rc = sriov_enable_migration(dev, nr_virtfn);
384 for (j = 0; j <
i; j++)
385 virtfn_remove(dev, j, 0);
399 static void sriov_disable(
struct pci_dev *dev)
408 sriov_disable_migration(dev);
411 virtfn_remove(dev, i, 0);
425 static int sriov_init(
struct pci_dev *dev,
int pos)
456 if (pci_ari_enabled(dev->bus))
463 if (!offset || (total > 1 && !stride))
468 pgsz &= ~((1 << i) - 1);
476 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
477 res = dev->resource + PCI_IOV_RESOURCES +
i;
482 if (resource_size(res) & (
PAGE_SIZE - 1)) {
486 res->
end = res->
start + resource_size(res) * total - 1;
523 res = dev->resource + PCI_IOV_RESOURCES +
i;
530 static void sriov_release(
struct pci_dev *dev)
532 BUG_ON(dev->sriov->nr_virtfn);
534 if (dev != dev->sriov->
dev)
543 static void sriov_restore_state(
struct pci_dev *dev)
549 pci_read_config_word(dev, iov->
pos + PCI_SRIOV_CTRL, &ctrl);
550 if (ctrl & PCI_SRIOV_CTRL_VFE)
553 for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
556 pci_write_config_dword(dev, iov->
pos + PCI_SRIOV_SYS_PGSIZE, iov->
pgsz);
558 pci_write_config_word(dev, iov->
pos + PCI_SRIOV_CTRL, iov->
ctrl);
559 if (iov->
ctrl & PCI_SRIOV_CTRL_VFE)
573 if (!pci_is_pcie(dev))
578 return sriov_init(dev, pos);
604 if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
612 4 * (resno - PCI_IOV_RESOURCES);
645 sriov_restore_state(dev);
664 busnr = virtfn_bus(dev, dev->sriov->total - 1);
669 return max ? max - bus->
number : 0;
686 return sriov_enable(dev, nr_virtfn);
735 return dev->sriov->nr_virtfn;