Re: [PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars

2017-12-20 Thread Juan Alvarez
On 12/19/17 12:38 AM, Alexey Kardashevskiy wrote:

> On 19/12/17 06:29, Juan Alvarez wrote:
>> This is PF only path. Yes either we have a root returned otherwise
>> will fall back to iomem_resource.
> You have removed context from my response, do not do that please.

My apologies. I will not do that.

>
> When will you have root and when you won't? imho it should always be either
> one or another.
>
Yes you are correct. The resource is carved out of a different mmio 
space and will never be passed in the assigned-addresses property in 
the device node of PF.

We will remove that function call, conditional check and set root accordingly.

>> On 12/18/17 1:21 AM, Alexey Kardashevskiy wrote:
>>> @dev here is a VF, right? I am not familiar with powervn much but from what
>>> I see - the devices are sitting on a root bus of their own PHB and they all
>>> either have a root returned from pci_find_parent_resource() or none of them
>>> has a root and will fall back to _resource, or both cases are 
>>> possible?
>
- Juan 



Re: [PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars

2017-12-18 Thread Alexey Kardashevskiy
On 19/12/17 06:29, Juan Alvarez wrote:
> This is PF only path. Yes either we have a root returned otherwise
> will fall back to iomem_resource.

You have removed context from my response, do not do that please.

When will you have root and when you won't? imho it should always be either
one or another.


> 
> On 12/18/17 1:21 AM, Alexey Kardashevskiy wrote:
>> @dev here is a VF, right? I am not familiar with powervn much but from what
>> I see - the devices are sitting on a root bus of their own PHB and they all
>> either have a root returned from pci_find_parent_resource() or none of them
>> has a root and will fall back to _resource, or both cases are possible?
> 


-- 
Alexey


Re: [PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars

2017-12-18 Thread Juan Alvarez
This is PF only path. Yes either we have a root returned otherwise
will fall back to iomem_resource.


On 12/18/17 1:21 AM, Alexey Kardashevskiy wrote:
> @dev here is a VF, right? I am not familiar with powervn much but from what
> I see - the devices are sitting on a root bus of their own PHB and they all
> either have a root returned from pci_find_parent_resource() or none of them
> has a root and will fall back to _resource, or both cases are possible?



Re: [PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars

2017-12-17 Thread Alexey Kardashevskiy
On 14/12/17 02:32, Bryant G. Ly wrote:
> When enabling SR-IOV in pseries platform,
> the VF bar properties for a PF are reported on
> the device node in the device tree.
> 
> This patch adds the IOV Bar resources to Linux
> structures from the device tree for later use
> when configuring SR-IOV by PF driver.
> 
> Signed-off-by: Bryant G. Ly 
> Signed-off-by: Juan J. Alvarez 
> ---
>  arch/powerpc/include/asm/pci.h |   2 +
>  arch/powerpc/kernel/pci_of_scan.c  |   2 +-
>  arch/powerpc/platforms/pseries/setup.c | 183 
> +
>  3 files changed, 186 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
> index 8dc32eacc97c..d82802ff5088 100644
> --- a/arch/powerpc/include/asm/pci.h
> +++ b/arch/powerpc/include/asm/pci.h
> @@ -121,6 +121,8 @@ extern int remove_phb_dynamic(struct pci_controller *phb);
>  extern struct pci_dev *of_create_pci_dev(struct device_node *node,
>   struct pci_bus *bus, int devfn);
>  
> +extern unsigned int pci_parse_of_flags(u32 addr0, int bridge);
> +
>  extern void of_scan_pci_bridge(struct pci_dev *dev);
>  
>  extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
> diff --git a/arch/powerpc/kernel/pci_of_scan.c 
> b/arch/powerpc/kernel/pci_of_scan.c
> index 0d790f8432d2..20ceec4a5f5e 100644
> --- a/arch/powerpc/kernel/pci_of_scan.c
> +++ b/arch/powerpc/kernel/pci_of_scan.c
> @@ -38,7 +38,7 @@ static u32 get_int_prop(struct device_node *np, const char 
> *name, u32 def)
>   * @addr0: value of 1st cell of a device tree PCI address.
>   * @bridge: Set this flag if the address is from a bridge 'ranges' property
>   */
> -static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
> +unsigned int pci_parse_of_flags(u32 addr0, int bridge)
>  {
>   unsigned int flags = 0;
>  
> diff --git a/arch/powerpc/platforms/pseries/setup.c 
> b/arch/powerpc/platforms/pseries/setup.c
> index 5f1beb8367ac..ce28882cbde8 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -459,6 +459,181 @@ static void __init find_and_init_phbs(void)
>   of_pci_check_probe_only();
>  }
>  
> +#ifdef CONFIG_PCI_IOV
> +enum rtas_iov_fw_value_map {
> + NUM_RES_PROPERTY  = 0, ///< Number of Resources
> + LOW_INT   = 1, ///< Lowest 32 bits of Address
> + START_OF_ENTRIES  = 2, ///< Always start of entry
> + APERTURE_PROPERTY = 2, ///< Start of entry+ to  Aperture Size
> + WDW_SIZE_PROPERTY = 4, ///< Start of entry+ to Window Size
> + NEXT_ENTRY= 7  ///< Go to next entry on array
> +};
> +
> +enum get_iov_fw_value_index {
> + BAR_ADDRS = 1,///<  Get Bar Address
> + APERTURE_SIZE = 2,///<  Get Aperture Size
> + WDW_SIZE  = 3 ///<  Get Window Size
> +};
> +
> +resource_size_t pseries_get_iov_fw_values(struct pci_dev *dev, int resno,

s/pseries_get_iov_fw_values/pseries_get_iov_fw_value/  as it returns a
single value.

> +   enum get_iov_fw_value_index value)
> +{
> + struct vf_bar_wdw {
> + __be64  addr;
> + __be64  aperture_size;
> + __be64  wdw_size;
> + };
> +
> + struct vf_bar_wdw window_avail[PCI_SRIOV_NUM_BARS];
> + const int *indexes;
> + struct device_node *dn = pci_device_to_OF_node(dev);
> + int i, r, num_res;
> + resource_size_t return_value;

resource_size_t return_value = 0;


and remove initialization below. Also, way too long, @ret is a more common
name.

> +
> + indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
> + if (!indexes)
> + return  0;
> +
> + memset(window_avail,
> +0, sizeof(struct vf_bar_wdw) * PCI_SRIOV_NUM_BARS);


This is more common way of doing the same initialization:

struct vf_bar_wdw {
__be64  addr;
__be64  aperture_size;
__be64  wdw_size;
} window_avail[PCI_SRIOV_NUM_BARS] = { 0 };



> + return_value = 0;
> + /*
> +  * First element in the array is the number of Bars
> +  * returned.  Search through the list to find the matching
> +  * bar
> +  */
> + num_res = of_read_number([NUM_RES_PROPERTY], 1);

if (resno >= num_res)
return 0; /* or an errror */

i = START_OF_ENTRIES + NEXT_ENTRY * resno;
switch (value) {
case BAR_ADDRS:
ret = f_read_number([i], 2);
break;
case APERTURE_SIZE:
ret = of_read_number([i + APERTURE_PROPERTY], 2);
break;
case WDW_SIZE:
ret = of_read_number([i + WDW_SIZE_PROPERTY], 2);
break;
}

return ret;
}

and remove the reminder of the function, and window_avail, and vf_bar_wdw?


> + for (i = START_OF_ENTRIES, r 

[PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars

2017-12-13 Thread Bryant G. Ly
When enabling SR-IOV in pseries platform,
the VF bar properties for a PF are reported on
the device node in the device tree.

This patch adds the IOV Bar resources to Linux
structures from the device tree for later use
when configuring SR-IOV by PF driver.

Signed-off-by: Bryant G. Ly 
Signed-off-by: Juan J. Alvarez 
---
 arch/powerpc/include/asm/pci.h |   2 +
 arch/powerpc/kernel/pci_of_scan.c  |   2 +-
 arch/powerpc/platforms/pseries/setup.c | 183 +
 3 files changed, 186 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 8dc32eacc97c..d82802ff5088 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -121,6 +121,8 @@ extern int remove_phb_dynamic(struct pci_controller *phb);
 extern struct pci_dev *of_create_pci_dev(struct device_node *node,
struct pci_bus *bus, int devfn);
 
+extern unsigned int pci_parse_of_flags(u32 addr0, int bridge);
+
 extern void of_scan_pci_bridge(struct pci_dev *dev);
 
 extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
diff --git a/arch/powerpc/kernel/pci_of_scan.c 
b/arch/powerpc/kernel/pci_of_scan.c
index 0d790f8432d2..20ceec4a5f5e 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -38,7 +38,7 @@ static u32 get_int_prop(struct device_node *np, const char 
*name, u32 def)
  * @addr0: value of 1st cell of a device tree PCI address.
  * @bridge: Set this flag if the address is from a bridge 'ranges' property
  */
-static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
+unsigned int pci_parse_of_flags(u32 addr0, int bridge)
 {
unsigned int flags = 0;
 
diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index 5f1beb8367ac..ce28882cbde8 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -459,6 +459,181 @@ static void __init find_and_init_phbs(void)
of_pci_check_probe_only();
 }
 
+#ifdef CONFIG_PCI_IOV
+enum rtas_iov_fw_value_map {
+   NUM_RES_PROPERTY  = 0, ///< Number of Resources
+   LOW_INT   = 1, ///< Lowest 32 bits of Address
+   START_OF_ENTRIES  = 2, ///< Always start of entry
+   APERTURE_PROPERTY = 2, ///< Start of entry+ to  Aperture Size
+   WDW_SIZE_PROPERTY = 4, ///< Start of entry+ to Window Size
+   NEXT_ENTRY= 7  ///< Go to next entry on array
+};
+
+enum get_iov_fw_value_index {
+   BAR_ADDRS = 1,///<  Get Bar Address
+   APERTURE_SIZE = 2,///<  Get Aperture Size
+   WDW_SIZE  = 3 ///<  Get Window Size
+};
+
+resource_size_t pseries_get_iov_fw_values(struct pci_dev *dev, int resno,
+ enum get_iov_fw_value_index value)
+{
+   struct vf_bar_wdw {
+   __be64  addr;
+   __be64  aperture_size;
+   __be64  wdw_size;
+   };
+
+   struct vf_bar_wdw window_avail[PCI_SRIOV_NUM_BARS];
+   const int *indexes;
+   struct device_node *dn = pci_device_to_OF_node(dev);
+   int i, r, num_res;
+   resource_size_t return_value;
+
+   indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
+   if (!indexes)
+   return  0;
+
+   memset(window_avail,
+  0, sizeof(struct vf_bar_wdw) * PCI_SRIOV_NUM_BARS);
+   return_value = 0;
+   /*
+* First element in the array is the number of Bars
+* returned.  Search through the list to find the matching
+* bar
+*/
+   num_res = of_read_number([NUM_RES_PROPERTY], 1);
+   for (i = START_OF_ENTRIES, r = 0; r < num_res && r < PCI_SRIOV_NUM_BARS;
+i += NEXT_ENTRY, r++) {
+   window_avail[r].addr = of_read_number([i], 2);
+   window_avail[r].aperture_size =
+   of_read_number([i + APERTURE_PROPERTY], 2);
+   window_avail[r].wdw_size =
+   of_read_number([i + WDW_SIZE_PROPERTY], 2);
+   }
+
+   switch (value) {
+   case BAR_ADDRS:
+   return_value = window_avail[resno].addr;
+   break;
+   case APERTURE_SIZE:
+   return_value = window_avail[resno].aperture_size;
+   break;
+   case WDW_SIZE:
+   return_value = window_avail[resno].wdw_size;
+   break;
+   default:
+   break;
+   }
+   return  return_value;
+}
+
+void of_pci_parse_vf_bar_size(struct pci_dev *dev, const int *indexes)
+{
+   struct resource *res;
+   resource_size_t base, size;
+   int i, r, num_res;
+
+   num_res = of_read_number([NUM_RES_PROPERTY], 1);
+   for (i = START_OF_ENTRIES, r = 0; r < num_res && r < PCI_SRIOV_NUM_BARS;
+i += NEXT_ENTRY, r++) {
+   res = >resource[r +