aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/pci-ioda.c
diff options
context:
space:
mode:
authorWei Yang <weiyang@linux.vnet.ibm.com>2015-10-21 21:22:14 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-02-09 20:04:54 -0500
commitb0331854190e70b9d96d39257230def45f832877 (patch)
treecb2bb4970c0f72011bef73235afbd37987d4937c /arch/powerpc/platforms/powernv/pci-ioda.c
parentccc9662da5494a7c4ff5ed5d167285b5a28d5fb3 (diff)
powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR
On PHB3, we enable SRIOV devices by mapping IOV BAR with M64 BARs. If a SRIOV device's IOV BAR is not 64bit-prefetchable, this is not assigned from 64bit prefetchable window, which means M64 BAR can't work on it. The reason is PCI bridges support only 2 memory windows and the kernel code programs bridges in the way that one window is 32bit-nonprefetchable and the other one is 64bit-prefetchable. So if devices' IOV BAR is 64bit and non-prefetchable, it will be mapped into 32bit space and therefore M64 cannot be used for it. This patch makes this explicit and truncate IOV resource in this case to save MMIO space. Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com> Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Acked-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci-ioda.c')
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 573ae1994097..58b0e230a382 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -872,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
872 if (!res->flags || !res->parent) 872 if (!res->flags || !res->parent)
873 continue; 873 continue;
874 874
875 if (!pnv_pci_is_mem_pref_64(res->flags))
876 continue;
877
878 /* 875 /*
879 * The actual IOV BAR range is determined by the start address 876 * The actual IOV BAR range is determined by the start address
880 * and the actual size for num_vfs VFs BAR. This check is to 877 * and the actual size for num_vfs VFs BAR. This check is to
@@ -903,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
903 if (!res->flags || !res->parent) 900 if (!res->flags || !res->parent)
904 continue; 901 continue;
905 902
906 if (!pnv_pci_is_mem_pref_64(res->flags))
907 continue;
908
909 size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); 903 size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
910 res2 = *res; 904 res2 = *res;
911 res->start += size * offset; 905 res->start += size * offset;
@@ -1263,9 +1257,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1263 if (!res->flags || !res->parent) 1257 if (!res->flags || !res->parent)
1264 continue; 1258 continue;
1265 1259
1266 if (!pnv_pci_is_mem_pref_64(res->flags))
1267 continue;
1268
1269 for (j = 0; j < vf_groups; j++) { 1260 for (j = 0; j < vf_groups; j++) {
1270 do { 1261 do {
1271 win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, 1262 win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
@@ -1552,6 +1543,12 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1552 pdn = pci_get_pdn(pdev); 1543 pdn = pci_get_pdn(pdev);
1553 1544
1554 if (phb->type == PNV_PHB_IODA2) { 1545 if (phb->type == PNV_PHB_IODA2) {
1546 if (!pdn->vfs_expanded) {
1547 dev_info(&pdev->dev, "don't support this SRIOV device"
1548 " with non 64bit-prefetchable IOV BAR\n");
1549 return -ENOSPC;
1550 }
1551
1555 /* Calculate available PE for required VFs */ 1552 /* Calculate available PE for required VFs */
1556 mutex_lock(&phb->ioda.pe_alloc_mutex); 1553 mutex_lock(&phb->ioda.pe_alloc_mutex);
1557 pdn->offset = bitmap_find_next_zero_area( 1554 pdn->offset = bitmap_find_next_zero_area(
@@ -2877,9 +2874,10 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2877 if (!res->flags || res->parent) 2874 if (!res->flags || res->parent)
2878 continue; 2875 continue;
2879 if (!pnv_pci_is_mem_pref_64(res->flags)) { 2876 if (!pnv_pci_is_mem_pref_64(res->flags)) {
2880 dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n", 2877 dev_warn(&pdev->dev, "Don't support SR-IOV with"
2878 " non M64 VF BAR%d: %pR. \n",
2881 i, res); 2879 i, res);
2882 continue; 2880 goto truncate_iov;
2883 } 2881 }
2884 2882
2885 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); 2883 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
@@ -2898,11 +2896,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2898 res = &pdev->resource[i + PCI_IOV_RESOURCES]; 2896 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2899 if (!res->flags || res->parent) 2897 if (!res->flags || res->parent)
2900 continue; 2898 continue;
2901 if (!pnv_pci_is_mem_pref_64(res->flags)) {
2902 dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
2903 i, res);
2904 continue;
2905 }
2906 2899
2907 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); 2900 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
2908 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); 2901 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
@@ -2912,6 +2905,16 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2912 i, res, mul); 2905 i, res, mul);
2913 } 2906 }
2914 pdn->vfs_expanded = mul; 2907 pdn->vfs_expanded = mul;
2908
2909 return;
2910
2911truncate_iov:
2912 /* To save MMIO space, IOV BAR is truncated. */
2913 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
2914 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2915 res->flags = 0;
2916 res->end = res->start - 1;
2917 }
2915} 2918}
2916#endif /* CONFIG_PCI_IOV */ 2919#endif /* CONFIG_PCI_IOV */
2917 2920