aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yang <weiyang@linux.vnet.ibm.com>2015-03-25 04:23:55 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-30 22:02:37 -0400
commit6e628c7d33d99406cef374972c89389edcc3570f (patch)
tree21a6a79faa895cd26f5127dfaba7b3423b2ae409
parent9e8d4a19ab66ec9e132d405357b9108a4f26efd3 (diff)
powerpc/powernv: Reserve additional space for IOV BAR according to the number of total_pe
On PHB3, PF IOV BAR will be covered by M64 BAR to have better PE isolation. M64 BAR is a type of hardware resource in PHB3, which could map a range of MMIO to PE numbers on powernv platform. And this range is divided equally by the number of total_pe with each divided range mapping to a PE number. Also, the M64 BAR must map a MMIO range with power-of-two size. The total_pe number is usually different from total_VFs, which can lead to a conflict between MMIO space and the PE number. For example, if total_VFs is 128 and total_pe is 256, the second half of M64 BAR will be part of other PCI device, which may already belong to other PEs. This patch prevents the conflict by reserving additional space for the PF IOV BAR, which is total_pe number of VF's BAR size. [bhelgaas: make dev_printk() output more consistent, index resource[] conventionally] Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/machdep.h4
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h3
-rw-r--r--arch/powerpc/kernel/pci-common.c6
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c43
4 files changed, 56 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 098d51e924ea..b303833fa3fb 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -250,6 +250,10 @@ struct machdep_calls {
250 /* Reset the secondary bus of bridge */ 250 /* Reset the secondary bus of bridge */
251 void (*pcibios_reset_secondary_bus)(struct pci_dev *dev); 251 void (*pcibios_reset_secondary_bus)(struct pci_dev *dev);
252 252
253#ifdef CONFIG_PCI_IOV
254 void (*pcibios_fixup_sriov)(struct pci_dev *pdev);
255#endif /* CONFIG_PCI_IOV */
256
253 /* Called to shutdown machine specific hardware not already controlled 257 /* Called to shutdown machine specific hardware not already controlled
254 * by other drivers. 258 * by other drivers.
255 */ 259 */
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index ece30f589398..7b8ebc5929ff 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -178,6 +178,9 @@ struct pci_dn {
178#define IODA_INVALID_PE (-1) 178#define IODA_INVALID_PE (-1)
179#ifdef CONFIG_PPC_POWERNV 179#ifdef CONFIG_PPC_POWERNV
180 int pe_number; 180 int pe_number;
181#ifdef CONFIG_PCI_IOV
182 u16 vfs_expanded; /* number of VFs IOV BAR expanded */
183#endif /* CONFIG_PCI_IOV */
181#endif 184#endif
182 struct list_head child_list; 185 struct list_head child_list;
183 struct list_head list; 186 struct list_head list;
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 82031011522f..375bf7099912 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -990,6 +990,12 @@ int pcibios_add_device(struct pci_dev *dev)
990 */ 990 */
991 if (dev->bus->is_added) 991 if (dev->bus->is_added)
992 pcibios_setup_device(dev); 992 pcibios_setup_device(dev);
993
994#ifdef CONFIG_PCI_IOV
995 if (ppc_md.pcibios_fixup_sriov)
996 ppc_md.pcibios_fixup_sriov(dev);
997#endif /* CONFIG_PCI_IOV */
998
993 return 0; 999 return 0;
994} 1000}
995 1001
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9447ee9b4aa3..1da45aa76a03 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1749,6 +1749,46 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
1749static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } 1749static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
1750#endif /* CONFIG_PCI_MSI */ 1750#endif /* CONFIG_PCI_MSI */
1751 1751
1752#ifdef CONFIG_PCI_IOV
1753static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
1754{
1755 struct pci_controller *hose;
1756 struct pnv_phb *phb;
1757 struct resource *res;
1758 int i;
1759 resource_size_t size;
1760 struct pci_dn *pdn;
1761
1762 if (!pdev->is_physfn || pdev->is_added)
1763 return;
1764
1765 hose = pci_bus_to_host(pdev->bus);
1766 phb = hose->private_data;
1767
1768 pdn = pci_get_pdn(pdev);
1769 pdn->vfs_expanded = 0;
1770
1771 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
1772 res = &pdev->resource[i + PCI_IOV_RESOURCES];
1773 if (!res->flags || res->parent)
1774 continue;
1775 if (!pnv_pci_is_mem_pref_64(res->flags)) {
1776 dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
1777 i, res);
1778 continue;
1779 }
1780
1781 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
1782 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
1783 res->end = res->start + size * phb->ioda.total_pe - 1;
1784 dev_dbg(&pdev->dev, " %pR\n", res);
1785 dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
1786 i, res, phb->ioda.total_pe);
1787 }
1788 pdn->vfs_expanded = phb->ioda.total_pe;
1789}
1790#endif /* CONFIG_PCI_IOV */
1791
1752/* 1792/*
1753 * This function is supposed to be called on basis of PE from top 1793 * This function is supposed to be called on basis of PE from top
1754 * to bottom style. So the the I/O or MMIO segment assigned to 1794 * 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,
2122 ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; 2162 ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
2123 ppc_md.pcibios_window_alignment = pnv_pci_window_alignment; 2163 ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
2124 ppc_md.pcibios_reset_secondary_bus = pnv_pci_reset_secondary_bus; 2164 ppc_md.pcibios_reset_secondary_bus = pnv_pci_reset_secondary_bus;
2165#ifdef CONFIG_PCI_IOV
2166 ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
2167#endif /* CONFIG_PCI_IOV */
2125 pci_add_flags(PCI_REASSIGN_ALL_RSRC); 2168 pci_add_flags(PCI_REASSIGN_ALL_RSRC);
2126 2169
2127 /* Reset IODA tables to a clean state */ 2170 /* Reset IODA tables to a clean state */