Commit 37b59ef0 authored by Oliver O'Halloran's avatar Oliver O'Halloran Committed by Michael Ellerman
Browse files

powerpc/powernv/sriov: Move SR-IOV into a separate file



pci-ioda.c is getting a bit unwieldly due to the amount of stuff jammed in
there. The SR-IOV support can be extracted easily enough and is mostly
standalone, so move it into a separate file.

This patch also moves the PowerNV SR-IOV specific fields from pci_dn and
moves them into a platform specific structure. I'm not sure how they ended
up in there in the first place, but leaking platform specifics into common
code has proven to be a terrible idea so far so lets stop doing that.

Signed-off-by: default avatarOliver O'Halloran <oohall@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200722065715.1432738-5-oohall@gmail.com
parent 36963365
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ struct dev_archdata {
#ifdef CONFIG_CXL_BASE
	struct cxl_context	*cxl_ctx;
#endif
#ifdef CONFIG_PCI_IOV
	void *iov_data;
#endif
};

struct pdev_archdata {
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ obj-$(CONFIG_FA_DUMP) += opal-fadump.o
obj-$(CONFIG_PRESERVE_FA_DUMP)	+= opal-fadump.o
obj-$(CONFIG_OPAL_CORE)	+= opal-core.o
obj-$(CONFIG_PCI)	+= pci.o pci-ioda.o npu-dma.o pci-ioda-tce.o
obj-$(CONFIG_PCI_IOV)   += pci-sriov.o
obj-$(CONFIG_CXL_BASE)	+= pci-cxl.o
obj-$(CONFIG_EEH)	+= eeh-powernv.o
obj-$(CONFIG_MEMORY_FAILURE)	+= opal-memory-errors.o
+18 −655

File changed.

Preview size limit exceeded, changes collapsed.

+640 −0

File added.

Preview size limit exceeded, changes collapsed.

+74 −0
Original line number Diff line number Diff line
@@ -194,6 +194,80 @@ struct pnv_phb {
	u8			*diag_data;
};


/* IODA PE management */

static inline bool pnv_pci_is_m64(struct pnv_phb *phb, struct resource *r)
{
	/*
	 * WARNING: We cannot rely on the resource flags. The Linux PCI
	 * allocation code sometimes decides to put a 64-bit prefetchable
	 * BAR in the 32-bit window, so we have to compare the addresses.
	 *
	 * For simplicity we only test resource start.
	 */
	return (r->start >= phb->ioda.m64_base &&
		r->start < (phb->ioda.m64_base + phb->ioda.m64_size));
}

static inline bool pnv_pci_is_m64_flags(unsigned long resource_flags)
{
	unsigned long flags = (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);

	return (resource_flags & flags) == flags;
}

int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe);
int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe);

void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe);
void pnv_pci_ioda2_release_pe_dma(struct pnv_ioda_pe *pe);

struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb);
void pnv_ioda_free_pe(struct pnv_ioda_pe *pe);

#ifdef CONFIG_PCI_IOV
/*
 * For SR-IOV we want to put each VF's MMIO resource in to a separate PE.
 * This requires a bit of acrobatics with the MMIO -> PE configuration
 * and this structure is used to keep track of it all.
 */
struct pnv_iov_data {
	/* number of VFs IOV BAR expanded. FIXME: rename this to something less bad */
	u16     vfs_expanded;

	/* number of VFs enabled */
	u16     num_vfs;
	unsigned int *pe_num_map;	/* PE# for the first VF PE or array */

	/* Did we map the VF BARs with single-PE IODA BARs? */
	bool    m64_single_mode;

	int     (*m64_map)[PCI_SRIOV_NUM_BARS];
#define IODA_INVALID_M64        (-1)

	/*
	 * If we map the SR-IOV BARs with a segmented window then
	 * parts of that window will be "claimed" by other PEs.
	 *
	 * "holes" here is used to reserve the leading portion
	 * of the window that is used by other (non VF) PEs.
	 */
	struct resource holes[PCI_SRIOV_NUM_BARS];
};

static inline struct pnv_iov_data *pnv_iov_get(struct pci_dev *pdev)
{
	return pdev->dev.archdata.iov_data;
}

void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev);
resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno);

int pnv_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs);
int pnv_pcibios_sriov_disable(struct pci_dev *pdev);
#endif /* CONFIG_PCI_IOV */

extern struct pci_ops pnv_pci_ops;

void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,