|
@@ -1749,6 +1749,46 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
|
|
|
static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
|
|
|
#endif /* CONFIG_PCI_MSI */
|
|
|
|
|
|
+#ifdef CONFIG_PCI_IOV
|
|
|
+static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
|
|
|
+{
|
|
|
+ struct pci_controller *hose;
|
|
|
+ struct pnv_phb *phb;
|
|
|
+ struct resource *res;
|
|
|
+ int i;
|
|
|
+ resource_size_t size;
|
|
|
+ struct pci_dn *pdn;
|
|
|
+
|
|
|
+ if (!pdev->is_physfn || pdev->is_added)
|
|
|
+ return;
|
|
|
+
|
|
|
+ hose = pci_bus_to_host(pdev->bus);
|
|
|
+ phb = hose->private_data;
|
|
|
+
|
|
|
+ pdn = pci_get_pdn(pdev);
|
|
|
+ pdn->vfs_expanded = 0;
|
|
|
+
|
|
|
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
|
|
|
+ res = &pdev->resource[i + PCI_IOV_RESOURCES];
|
|
|
+ if (!res->flags || res->parent)
|
|
|
+ continue;
|
|
|
+ if (!pnv_pci_is_mem_pref_64(res->flags)) {
|
|
|
+ dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
|
|
|
+ i, res);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
|
|
|
+ size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
|
|
|
+ res->end = res->start + size * phb->ioda.total_pe - 1;
|
|
|
+ dev_dbg(&pdev->dev, " %pR\n", res);
|
|
|
+ dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
|
|
|
+ i, res, phb->ioda.total_pe);
|
|
|
+ }
|
|
|
+ pdn->vfs_expanded = phb->ioda.total_pe;
|
|
|
+}
|
|
|
+#endif /* CONFIG_PCI_IOV */
|
|
|
+
|
|
|
/*
|
|
|
* This function is supposed to be called on basis of PE from top
|
|
|
* to bottom style. So the the I/O or MMIO segment assigned to
|
|
@@ -2122,6 +2162,9 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|
|
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
|
|
|
ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
|
|
|
ppc_md.pcibios_reset_secondary_bus = pnv_pci_reset_secondary_bus;
|
|
|
+#ifdef CONFIG_PCI_IOV
|
|
|
+ ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
|
|
|
+#endif /* CONFIG_PCI_IOV */
|
|
|
pci_add_flags(PCI_REASSIGN_ALL_RSRC);
|
|
|
|
|
|
/* Reset IODA tables to a clean state */
|