Re: [PATCH V14 17/21] powerpc/powernv: Shift VF resource with an offset

2015-03-23 Thread Daniel Axtens
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

2015-03-23 Thread Wei Yang
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

2015-03-19 Thread Wei Yang
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;
+
+   /*