Re: [PATCH V14 17/21] powerpc/powernv: Shift VF resource with an offset
On Fri, 2015-03-20 at 11:06 +0800, Wei Yang wrote: On PowerNV platform, resource position in M64 BAR implies the PE# the resource belongs to. In some cases, adjustment of a resource is necessary to locate it to a correct position in M64 BAR . This patch adds pnv_pci_vf_resource_shift() to shift the 'real' PF IOV BAR address according to an offset. Note: After doing so, there would be a hole in the /proc/iomem when offset is a positive value. It looks like the device return some mmio back to the system, which actually no one could use it. [bhelgaas: rework loops, rework overlap check, index resource[] conventionally, remove pci_regs.h include, squashed with next patch] Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com --- arch/powerpc/include/asm/pci-bridge.h |4 + arch/powerpc/kernel/pci_dn.c | 13 + arch/powerpc/platforms/powernv/pci-ioda.c | 524 - arch/powerpc/platforms/powernv/pci.c | 18 + arch/powerpc/platforms/powernv/pci.h |7 + 5 files changed, 549 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index d0d1718..3c95097 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -177,6 +177,10 @@ struct pci_dn { int pe_number; #ifdef CONFIG_PCI_IOV u16 vfs_expanded; /* number of VFs IOV BAR expanded */ + u16 num_vfs;/* number of VFs enabled*/ + int offset; /* PE# for the first VF PE */ +#define IODA_INVALID_M64(-1) + int m64_wins[PCI_SRIOV_NUM_BARS]; #endif /* CONFIG_PCI_IOV */ #endif struct list_head child_list; diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index f3a1a81..93ed7b3 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -217,6 +217,19 @@ void remove_dev_pci_info(struct pci_dev *pdev) struct pci_dn *pdn, *tmp; int i; + /* + * VF and VF PE are created/released dynamically, so we need to + * bind/unbind them. Otherwise the VF and VF PE would be mismatched + * when re-enabling SR-IOV. + */ + if (pdev-is_virtfn) { + pdn = pci_get_pdn(pdev); +#ifdef CONFIG_PPC_POWERNV + pdn-pe_number = IODA_INVALID_PE; +#endif + return; + } + /* Only support IOV PF for now */ if (!pdev-is_physfn) return; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 93ec16c..bd1b678 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -44,6 +44,9 @@ #include powernv.h #include pci.h +/* 256M DMA window, 4K TCE pages, 8 bytes TCE */ +#define TCE32_TABLE_SIZE ((0x1000 / 0x1000) * 8) + static void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, const char *fmt, ...) { @@ -56,11 +59,18 @@ static void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, vaf.fmt = fmt; vaf.va = args; - if (pe-pdev) + if (pe-flags PNV_IODA_PE_DEV) strlcpy(pfix, dev_name(pe-pdev-dev), sizeof(pfix)); - else + else if (pe-flags (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) sprintf(pfix, %04x:%02x , pci_domain_nr(pe-pbus), pe-pbus-number); +#ifdef CONFIG_PCI_IOV + else if (pe-flags PNV_IODA_PE_VF) + sprintf(pfix, %04x:%02x:%2x.%d, + pci_domain_nr(pe-parent_dev-bus), + (pe-rid 0xff00) 8, + PCI_SLOT(pe-rid), PCI_FUNC(pe-rid)); +#endif /* CONFIG_PCI_IOV*/ printk(%spci %s: [PE# %.3d] %pV, level, pfix, pe-pe_number, vaf); @@ -591,7 +601,7 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, bool is_add) { struct pnv_ioda_pe *slave; - struct pci_dev *pdev; + struct pci_dev *pdev = NULL; int ret; /* @@ -630,8 +640,12 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, if (pe-flags (PNV_IODA_PE_BUS_ALL | PNV_IODA_PE_BUS)) pdev = pe-pbus-self; - else + else if (pe-flags PNV_IODA_PE_DEV) pdev = pe-pdev-bus-self; +#ifdef CONFIG_PCI_IOV + else if (pe-flags PNV_IODA_PE_VF) + pdev = pe-parent_dev-bus-self; +#endif /* CONFIG_PCI_IOV */ while (pdev) { struct pci_dn *pdn = pci_get_pdn(pdev); struct pnv_ioda_pe *parent; @@ -649,6 +663,87 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, return 0; } +#ifdef CONFIG_PCI_IOV +static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) +{ + struct pci_dev *parent; + uint8_t bcomp,
Re: [PATCH V14 17/21] powerpc/powernv: Shift VF resource with an offset
On Tue, Mar 24, 2015 at 10:22:26AM +1100, Daniel Axtens wrote: + +/* Do some magic shift */ +ret = pnv_pci_vf_resource_shift(pdev, pdn-offset); Given that you're already doing a version 15, would it be possible to include a more informative comment than Do some magic shift? Perhaps some of the information from your commit message? Regards, Daniel Daniel, Thanks for your comment, I will add more informative comment at this place. -- Richard Yang Help you, Help me ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V14 17/21] powerpc/powernv: Shift VF resource with an offset
On PowerNV platform, resource position in M64 BAR implies the PE# the resource belongs to. In some cases, adjustment of a resource is necessary to locate it to a correct position in M64 BAR . This patch adds pnv_pci_vf_resource_shift() to shift the 'real' PF IOV BAR address according to an offset. Note: After doing so, there would be a hole in the /proc/iomem when offset is a positive value. It looks like the device return some mmio back to the system, which actually no one could use it. [bhelgaas: rework loops, rework overlap check, index resource[] conventionally, remove pci_regs.h include, squashed with next patch] Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com --- arch/powerpc/include/asm/pci-bridge.h |4 + arch/powerpc/kernel/pci_dn.c | 13 + arch/powerpc/platforms/powernv/pci-ioda.c | 524 - arch/powerpc/platforms/powernv/pci.c | 18 + arch/powerpc/platforms/powernv/pci.h |7 + 5 files changed, 549 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index d0d1718..3c95097 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -177,6 +177,10 @@ struct pci_dn { int pe_number; #ifdef CONFIG_PCI_IOV u16 vfs_expanded; /* number of VFs IOV BAR expanded */ + u16 num_vfs;/* number of VFs enabled*/ + int offset; /* PE# for the first VF PE */ +#define IODA_INVALID_M64(-1) + int m64_wins[PCI_SRIOV_NUM_BARS]; #endif /* CONFIG_PCI_IOV */ #endif struct list_head child_list; diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index f3a1a81..93ed7b3 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -217,6 +217,19 @@ void remove_dev_pci_info(struct pci_dev *pdev) struct pci_dn *pdn, *tmp; int i; + /* +* VF and VF PE are created/released dynamically, so we need to +* bind/unbind them. Otherwise the VF and VF PE would be mismatched +* when re-enabling SR-IOV. +*/ + if (pdev-is_virtfn) { + pdn = pci_get_pdn(pdev); +#ifdef CONFIG_PPC_POWERNV + pdn-pe_number = IODA_INVALID_PE; +#endif + return; + } + /* Only support IOV PF for now */ if (!pdev-is_physfn) return; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 93ec16c..bd1b678 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -44,6 +44,9 @@ #include powernv.h #include pci.h +/* 256M DMA window, 4K TCE pages, 8 bytes TCE */ +#define TCE32_TABLE_SIZE ((0x1000 / 0x1000) * 8) + static void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, const char *fmt, ...) { @@ -56,11 +59,18 @@ static void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, vaf.fmt = fmt; vaf.va = args; - if (pe-pdev) + if (pe-flags PNV_IODA_PE_DEV) strlcpy(pfix, dev_name(pe-pdev-dev), sizeof(pfix)); - else + else if (pe-flags (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) sprintf(pfix, %04x:%02x , pci_domain_nr(pe-pbus), pe-pbus-number); +#ifdef CONFIG_PCI_IOV + else if (pe-flags PNV_IODA_PE_VF) + sprintf(pfix, %04x:%02x:%2x.%d, + pci_domain_nr(pe-parent_dev-bus), + (pe-rid 0xff00) 8, + PCI_SLOT(pe-rid), PCI_FUNC(pe-rid)); +#endif /* CONFIG_PCI_IOV*/ printk(%spci %s: [PE# %.3d] %pV, level, pfix, pe-pe_number, vaf); @@ -591,7 +601,7 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, bool is_add) { struct pnv_ioda_pe *slave; - struct pci_dev *pdev; + struct pci_dev *pdev = NULL; int ret; /* @@ -630,8 +640,12 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, if (pe-flags (PNV_IODA_PE_BUS_ALL | PNV_IODA_PE_BUS)) pdev = pe-pbus-self; - else + else if (pe-flags PNV_IODA_PE_DEV) pdev = pe-pdev-bus-self; +#ifdef CONFIG_PCI_IOV + else if (pe-flags PNV_IODA_PE_VF) + pdev = pe-parent_dev-bus-self; +#endif /* CONFIG_PCI_IOV */ while (pdev) { struct pci_dn *pdn = pci_get_pdn(pdev); struct pnv_ioda_pe *parent; @@ -649,6 +663,87 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb, return 0; } +#ifdef CONFIG_PCI_IOV +static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) +{ + struct pci_dev *parent; + uint8_t bcomp, dcomp, fcomp; + int64_t rc; + long rid_end, rid; + + /*