| From 7d4f3e872125b383d2871875611fd6b17cd5b9c1 Mon Sep 17 00:00:00 2001 |
| From: Oliver O'Halloran <oohall@gmail.com> |
| Date: Fri, 10 Jan 2020 18:02:05 +1100 |
| Subject: [PATCH] powerpc/iov: Move VF pdev fixup into pcibios_fixup_iov() |
| |
| commit 965c94f309be58fbcc6c8d3e4f123376c5970d79 upstream. |
| |
| An ioda_pe for each VF is allocated in pnv_pci_sriov_enable() before |
| the pci_dev for the VF is created. We need to set the pe->pdev pointer |
| at some point after the pci_dev is created. Currently we do that in: |
| |
| pcibios_bus_add_device() |
| pnv_pci_dma_dev_setup() (via phb->ops.dma_dev_setup) |
| /* fixup is done here */ |
| pnv_pci_ioda_dma_dev_setup() (via pnv_phb->dma_dev_setup) |
| |
| The fixup needs to be done before setting up DMA for for the VF's PE, |
| but there's no real reason to delay it until this point. Move the |
| fixup into pnv_pci_ioda_fixup_iov() so the ordering is: |
| |
| pcibios_add_device() |
| pnv_pci_ioda_fixup_iov() (via ppc_md.pcibios_fixup_sriov) |
| |
| pcibios_bus_add_device() |
| ... |
| |
| This isn't strictly required, but it's a slightly more logical place |
| to do the fixup and it simplifies pnv_pci_dma_dev_setup(). |
| |
| Signed-off-by: Oliver O'Halloran <oohall@gmail.com> |
| Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Link: https://lore.kernel.org/r/20200110070207.439-4-oohall@gmail.com |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c |
| index 295f47fb0578..050131e886f1 100644 |
| --- a/arch/powerpc/platforms/powernv/pci-ioda.c |
| +++ b/arch/powerpc/platforms/powernv/pci-ioda.c |
| @@ -2908,9 +2908,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) |
| struct pci_dn *pdn; |
| int mul, total_vfs; |
| |
| - if (!pdev->is_physfn || pci_dev_is_added(pdev)) |
| - return; |
| - |
| pdn = pci_get_pdn(pdev); |
| pdn->vfs_expanded = 0; |
| pdn->m64_single_mode = false; |
| @@ -2985,6 +2982,30 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) |
| res->end = res->start - 1; |
| } |
| } |
| + |
| +static void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev) |
| +{ |
| + if (WARN_ON(pci_dev_is_added(pdev))) |
| + return; |
| + |
| + if (pdev->is_virtfn) { |
| + struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev); |
| + |
| + /* |
| + * VF PEs are single-device PEs so their pdev pointer needs to |
| + * be set. The pdev doesn't exist when the PE is allocated (in |
| + * (pcibios_sriov_enable()) so we fix it up here. |
| + */ |
| + pe->pdev = pdev; |
| + WARN_ON(!(pe->flags & PNV_IODA_PE_VF)); |
| + } else if (pdev->is_physfn) { |
| + /* |
| + * For PFs adjust their allocated IOV resources to match what |
| + * the PHB can support using it's M64 BAR table. |
| + */ |
| + pnv_pci_ioda_fixup_iov_resources(pdev); |
| + } |
| +} |
| #endif /* CONFIG_PCI_IOV */ |
| |
| static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe, |
| @@ -3881,7 +3902,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, |
| ppc_md.pcibios_default_alignment = pnv_pci_default_alignment; |
| |
| #ifdef CONFIG_PCI_IOV |
| - ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources; |
| + ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov; |
| ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment; |
| ppc_md.pcibios_sriov_enable = pnv_pcibios_sriov_enable; |
| ppc_md.pcibios_sriov_disable = pnv_pcibios_sriov_disable; |
| diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c |
| index 13ac322dcc47..2bfb72d057a7 100644 |
| --- a/arch/powerpc/platforms/powernv/pci.c |
| +++ b/arch/powerpc/platforms/powernv/pci.c |
| @@ -814,20 +814,6 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev) |
| { |
| struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
| struct pnv_phb *phb = hose->private_data; |
| -#ifdef CONFIG_PCI_IOV |
| - struct pnv_ioda_pe *pe; |
| - |
| - /* Fix the VF pdn PE number */ |
| - if (pdev->is_virtfn) { |
| - list_for_each_entry(pe, &phb->ioda.pe_list, list) { |
| - if (pe->rid == ((pdev->bus->number << 8) | |
| - (pdev->devfn & 0xff))) { |
| - pe->pdev = pdev; |
| - break; |
| - } |
| - } |
| - } |
| -#endif /* CONFIG_PCI_IOV */ |
| |
| if (phb && phb->dma_dev_setup) |
| phb->dma_dev_setup(phb, pdev); |
| -- |
| 2.7.4 |
| |