Re: [PATCH v1 7/7] pseries/setup: Add Initialization of VF Bars
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
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
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
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
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. LySigned-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 +