[Very RFC 28/46] powernv/iov: Move SR-IOV PF state out of pci_dn
Alexey Kardashevskiy
aik at ozlabs.ru
Wed Nov 27 15:09:45 AEDT 2019
On 20/11/2019 12:28, Oliver O'Halloran wrote:
> Move the SR-IOV into a platform specific structure. I'm sure stashing all the
> SR-IOV state in pci_dn seemed like a good idea at the time, but it results in a
> lot of powernv specifics being leaked out of the platform directory.
>
> Moving all the PHB3/4 specific M64 BAR wrangling into a PowerNV specific
> structure helps to clarify the role of pci_dn and ensures that the platform
> specifics stay that way.
>
> This will make the code easier to understand and modify since we don't need
> to so much aboute PowerNV changes breaking pseries and EEH, and vis-a-vis.
>
> Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
> ---
> TODO: Remove all the sriov stuff from pci_dn. We can't do that yet because
> the pseries SRIOV support was a giant hack that re-used some of the
> previously powernv specific fields.
> ---
> arch/powerpc/include/asm/device.h | 3 +
> arch/powerpc/platforms/powernv/pci-ioda.c | 199 ++++++++++++----------
> arch/powerpc/platforms/powernv/pci.h | 36 ++++
> 3 files changed, 148 insertions(+), 90 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
> index 266542769e4b..4d8934db7ef5 100644
> --- a/arch/powerpc/include/asm/device.h
> +++ b/arch/powerpc/include/asm/device.h
> @@ -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 {
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index a1c9315f3208..1c90feed233d 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -966,14 +966,15 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
> #ifdef CONFIG_PCI_IOV
> static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
> {
> - struct pci_dn *pdn = pci_get_pdn(dev);
> - int i;
> struct resource *res, res2;
> + struct pnv_iov_data *iov;
> resource_size_t size;
> u16 num_vfs;
> + int i;
>
> if (!dev->is_physfn)
> return -EINVAL;
> + iov = pnv_iov_get(dev);
>
> /*
> * "offset" is in VFs. The M64 windows are sized so that when they
> @@ -983,7 +984,7 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
> * separate PE, and changing the IOV BAR start address changes the
> * range of PEs the VFs are in.
> */
> - num_vfs = pdn->num_vfs;
> + num_vfs = iov->num_vfs;
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> res = &dev->resource[i + PCI_IOV_RESOURCES];
> if (!res->flags || !res->parent)
> @@ -1029,19 +1030,19 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
> num_vfs, offset);
>
> if (offset < 0) {
> - devm_release_resource(&dev->dev, &pdn->holes[i]);
> - memset(&pdn->holes[i], 0, sizeof(pdn->holes[i]));
> + devm_release_resource(&dev->dev, &iov->holes[i]);
> + memset(&iov->holes[i], 0, sizeof(iov->holes[i]));
> }
>
> pci_update_resource(dev, i + PCI_IOV_RESOURCES);
>
> if (offset > 0) {
> - pdn->holes[i].start = res2.start;
> - pdn->holes[i].end = res2.start + size * offset - 1;
> - pdn->holes[i].flags = IORESOURCE_BUS;
> - pdn->holes[i].name = "pnv_iov_reserved";
> + iov->holes[i].start = res2.start;
> + iov->holes[i].end = res2.start + size * offset - 1;
> + iov->holes[i].flags = IORESOURCE_BUS;
> + iov->holes[i].name = "pnv_iov_reserved";
> devm_request_resource(&dev->dev, res->parent,
> - &pdn->holes[i]);
> + &iov->holes[i]);
> }
> }
> return 0;
> @@ -1273,37 +1274,37 @@ static void pnv_pci_ioda_setup_PEs(void)
> #ifdef CONFIG_PCI_IOV
> static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs)
> {
> + struct pnv_iov_data *iov;
> struct pnv_phb *phb;
> - struct pci_dn *pdn;
> int i, j;
> int m64_bars;
>
> phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
> + iov = pnv_iov_get(pdev);
>
> - if (pdn->m64_single_mode)
> + if (iov->m64_single_mode)
> m64_bars = num_vfs;
> else
> m64_bars = 1;
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
> for (j = 0; j < m64_bars; j++) {
> - if (pdn->m64_map[j][i] == IODA_INVALID_M64)
> + if (iov->m64_map[j][i] == IODA_INVALID_M64)
> continue;
> opal_pci_phb_mmio_enable(phb->opal_id,
> - OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0);
> - clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc);
> - pdn->m64_map[j][i] = IODA_INVALID_M64;
> + OPAL_M64_WINDOW_TYPE, iov->m64_map[j][i], 0);
> + clear_bit(iov->m64_map[j][i], &phb->ioda.m64_bar_alloc);
> + iov->m64_map[j][i] = IODA_INVALID_M64;
> }
>
> - kfree(pdn->m64_map);
> + kfree(iov->m64_map);
> return 0;
> }
>
> static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> {
> + struct pnv_iov_data *iov;
> struct pnv_phb *phb;
> - struct pci_dn *pdn;
> unsigned int win;
> struct resource *res;
> int i, j;
> @@ -1314,23 +1315,23 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> int m64_bars;
>
> phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
> + iov = pnv_iov_get(pdev);
> total_vfs = pci_sriov_get_totalvfs(pdev);
>
> - if (pdn->m64_single_mode)
> + if (iov->m64_single_mode)
> m64_bars = num_vfs;
> else
> m64_bars = 1;
>
> - pdn->m64_map = kmalloc_array(m64_bars,
> - sizeof(*pdn->m64_map),
> + iov->m64_map = kmalloc_array(m64_bars,
> + sizeof(*iov->m64_map),
> GFP_KERNEL);
> - if (!pdn->m64_map)
> + if (!iov->m64_map)
> return -ENOMEM;
> /* Initialize the m64_map to IODA_INVALID_M64 */
> for (i = 0; i < m64_bars ; i++)
> for (j = 0; j < PCI_SRIOV_NUM_BARS; j++)
> - pdn->m64_map[i][j] = IODA_INVALID_M64;
> + iov->m64_map[i][j] = IODA_INVALID_M64;
>
>
> for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
> @@ -1347,9 +1348,9 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> goto m64_failed;
> } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
>
> - pdn->m64_map[j][i] = win;
> + iov->m64_map[j][i] = win;
>
> - if (pdn->m64_single_mode) {
> + if (iov->m64_single_mode) {
> size = pci_iov_resource_size(pdev,
> PCI_IOV_RESOURCES + i);
> start = res->start + size * j;
> @@ -1359,16 +1360,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> }
>
> /* Map the M64 here */
> - if (pdn->m64_single_mode) {
> - pe_num = pdn->pe_num_map[j];
> + if (iov->m64_single_mode) {
> + pe_num = iov->pe_num_map[j];
> rc = opal_pci_map_pe_mmio_window(phb->opal_id,
> pe_num, OPAL_M64_WINDOW_TYPE,
> - pdn->m64_map[j][i], 0);
> + iov->m64_map[j][i], 0);
> }
>
> rc = opal_pci_set_phb_mem_window(phb->opal_id,
> OPAL_M64_WINDOW_TYPE,
> - pdn->m64_map[j][i],
> + iov->m64_map[j][i],
> start,
> 0, /* unused */
> size);
> @@ -1380,12 +1381,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
> goto m64_failed;
> }
>
> - if (pdn->m64_single_mode)
> + if (iov->m64_single_mode)
> rc = opal_pci_phb_mmio_enable(phb->opal_id,
> - OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2);
> + OPAL_M64_WINDOW_TYPE, iov->m64_map[j][i], 2);
> else
> rc = opal_pci_phb_mmio_enable(phb->opal_id,
> - OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1);
> + OPAL_M64_WINDOW_TYPE, iov->m64_map[j][i], 1);
>
> if (rc != OPAL_SUCCESS) {
> dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n",
> @@ -1426,10 +1427,8 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev)
> {
> struct pnv_phb *phb;
> struct pnv_ioda_pe *pe, *pe_n;
> - struct pci_dn *pdn;
>
> phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
Looks like an unrelated cleanup.
>
> if (!pdev->is_physfn)
> return;
> @@ -1455,36 +1454,36 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
> {
> struct pnv_phb *phb;
> struct pnv_ioda_pe *pe;
> - struct pci_dn *pdn;
> + struct pnv_iov_data *iov;
> u16 num_vfs, i;
>
> phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
> - num_vfs = pdn->num_vfs;
> + iov = pnv_iov_get(pdev);
> + num_vfs = iov->num_vfs;
>
> /* Release VF PEs */
> pnv_ioda_release_vf_PE(pdev);
>
> if (phb->type == PNV_PHB_IODA2) {
> - if (!pdn->m64_single_mode)
> - pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map);
> + if (!iov->m64_single_mode)
> + pnv_pci_vf_resource_shift(pdev, -*iov->pe_num_map);
>
> /* Release M64 windows */
> pnv_pci_vf_release_m64(pdev, num_vfs);
>
> /* Release PE numbers */
> - if (pdn->m64_single_mode) {
> + if (iov->m64_single_mode) {
> for (i = 0; i < num_vfs; i++) {
> - if (pdn->pe_num_map[i] == IODA_INVALID_PE)
> + if (iov->pe_num_map[i] == IODA_INVALID_PE)
> continue;
>
> - pe = &phb->ioda.pe_array[pdn->pe_num_map[i]];
> + pe = &phb->ioda.pe_array[iov->pe_num_map[i]];
> pnv_ioda_free_pe(pe);
> }
> } else
> - bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
> + bitmap_clear(phb->ioda.pe_alloc, *iov->pe_num_map, num_vfs);
> /* Releasing pe_num_map */
> - kfree(pdn->pe_num_map);
> + kfree(iov->pe_num_map);
> }
> }
>
> @@ -1501,24 +1500,24 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
> struct pnv_ioda_pe *pe;
> int pe_num;
> u16 vf_index;
> - struct pci_dn *pdn;
> -
> - phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
> + struct pnv_iov_data *iov;
>
> if (!pdev->is_physfn)
> return;
>
> + phb = pci_bus_to_pnvhb(pdev->bus);
> + iov = pnv_iov_get(pdev);
> +
> /* Reserve PE for each VF */
> for (vf_index = 0; vf_index < num_vfs; vf_index++) {
> int vf_devfn = pci_iov_virtfn_devfn(pdev, vf_index);
> int vf_bus = pci_iov_virtfn_bus(pdev, vf_index);
> struct pci_dn *vf_pdn;
>
> - if (pdn->m64_single_mode)
> - pe_num = pdn->pe_num_map[vf_index];
> + if (iov->m64_single_mode)
> + pe_num = iov->pe_num_map[vf_index];
> else
> - pe_num = *pdn->pe_num_map + vf_index;
> + pe_num = *iov->pe_num_map + vf_index;
>
> pe = &phb->ioda.pe_array[pe_num];
> pe->pe_number = pe_num;
> @@ -1565,17 +1564,17 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
>
> int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> {
> + struct pnv_iov_data *iov;
> struct pnv_phb *phb;
> struct pnv_ioda_pe *pe;
> - struct pci_dn *pdn;
> int ret;
> u16 i;
>
> phb = pci_bus_to_pnvhb(pdev->bus);
> - pdn = pci_get_pdn(pdev);
> + iov = pnv_iov_get(pdev);
>
> if (phb->type == PNV_PHB_IODA2) {
> - if (!pdn->vfs_expanded) {
> + if (!iov->vfs_expanded) {
> dev_info(&pdev->dev, "don't support this SRIOV device"
> " with non 64bit-prefetchable IOV BAR\n");
> return -ENOSPC;
> @@ -1585,28 +1584,26 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> * When M64 BARs functions in Single PE mode, the number of VFs
> * could be enabled must be less than the number of M64 BARs.
> */
> - if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
> + if (iov->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
> dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n");
> return -EBUSY;
> }
>
> /* Allocating pe_num_map */
> - if (pdn->m64_single_mode)
> - pdn->pe_num_map = kmalloc_array(num_vfs,
> - sizeof(*pdn->pe_num_map),
> - GFP_KERNEL);
> + if (iov->m64_single_mode)
> + iov->pe_num_map = kmalloc_array(num_vfs, sizeof(*iov->pe_num_map), GFP_KERNEL);
> else
> - pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL);
> + iov->pe_num_map = kmalloc(sizeof(*iov->pe_num_map), GFP_KERNEL);
>
> - if (!pdn->pe_num_map)
> + if (!iov->pe_num_map)
> return -ENOMEM;
>
> - if (pdn->m64_single_mode)
> + if (iov->m64_single_mode)
> for (i = 0; i < num_vfs; i++)
> - pdn->pe_num_map[i] = IODA_INVALID_PE;
> + iov->pe_num_map[i] = IODA_INVALID_PE;
>
> /* Calculate available PE for required VFs */
> - if (pdn->m64_single_mode) {
> + if (iov->m64_single_mode) {
> for (i = 0; i < num_vfs; i++) {
> pe = pnv_ioda_alloc_pe(phb);
> if (!pe) {
> @@ -1614,23 +1611,23 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> goto m64_failed;
> }
>
> - pdn->pe_num_map[i] = pe->pe_number;
> + iov->pe_num_map[i] = pe->pe_number;
> }
> } else {
> mutex_lock(&phb->ioda.pe_alloc_mutex);
> - *pdn->pe_num_map = bitmap_find_next_zero_area(
> + *iov->pe_num_map = bitmap_find_next_zero_area(
> phb->ioda.pe_alloc, phb->ioda.total_pe_num,
> 0, num_vfs, 0);
> - if (*pdn->pe_num_map >= phb->ioda.total_pe_num) {
> + if (*iov->pe_num_map >= phb->ioda.total_pe_num) {
> mutex_unlock(&phb->ioda.pe_alloc_mutex);
> dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
> - kfree(pdn->pe_num_map);
> + kfree(iov->pe_num_map);
> return -EBUSY;
> }
> - bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
> + bitmap_set(phb->ioda.pe_alloc, *iov->pe_num_map, num_vfs);
> mutex_unlock(&phb->ioda.pe_alloc_mutex);
> }
> - pdn->num_vfs = num_vfs;
> + iov->num_vfs = num_vfs;
>
> /* Assign M64 window accordingly */
> ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
> @@ -1644,8 +1641,8 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> * the IOV BAR according to the PE# allocated to the VFs.
> * Otherwise, the PE# for the VF will conflict with others.
> */
> - if (!pdn->m64_single_mode) {
> - ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map);
> + if (!iov->m64_single_mode) {
> + ret = pnv_pci_vf_resource_shift(pdev, *iov->pe_num_map);
> if (ret)
> goto m64_failed;
> }
> @@ -1657,19 +1654,19 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
> return 0;
>
> m64_failed:
> - if (pdn->m64_single_mode) {
> + if (iov->m64_single_mode) {
> for (i = 0; i < num_vfs; i++) {
> - if (pdn->pe_num_map[i] == IODA_INVALID_PE)
> + if (iov->pe_num_map[i] == IODA_INVALID_PE)
> continue;
>
> - pe = &phb->ioda.pe_array[pdn->pe_num_map[i]];
> + pe = &phb->ioda.pe_array[iov->pe_num_map[i]];
> pnv_ioda_free_pe(pe);
> }
> } else
> - bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
> + bitmap_clear(phb->ioda.pe_alloc, *iov->pe_num_map, num_vfs);
>
> /* Releasing pe_num_map */
> - kfree(pdn->pe_num_map);
> + kfree(iov->pe_num_map);
>
> return ret;
> }
> @@ -2840,12 +2837,13 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> struct resource *res;
> int i;
> resource_size_t size, total_vf_bar_sz;
> - struct pci_dn *pdn;
> + struct pnv_iov_data *iov;
> int mul, total_vfs;
>
> - pdn = pci_get_pdn(pdev);
> - pdn->vfs_expanded = 0;
> - pdn->m64_single_mode = false;
> + iov = kzalloc(sizeof(*iov), GFP_KERNEL);
> + if (!iov)
> + goto truncate_iov;
> + pdev->dev.archdata.iov_data = iov;
>
> total_vfs = pci_sriov_get_totalvfs(pdev);
> mul = phb->ioda.total_pe_num;
> @@ -2882,7 +2880,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> dev_info(&pdev->dev,
> "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n",
> total_vf_bar_sz, gate, mul);
> - pdn->m64_single_mode = true;
> + iov->m64_single_mode = true;
> break;
> }
> }
> @@ -2897,7 +2895,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> * On PHB3, the minimum size alignment of M64 BAR in single
> * mode is 32MB.
> */
> - if (pdn->m64_single_mode && (size < SZ_32M))
> + if (iov->m64_single_mode && (size < SZ_32M))
> goto truncate_iov;
> dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
> res->end = res->start + size * mul - 1;
> @@ -2905,7 +2903,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
> i, res, mul);
> }
> - pdn->vfs_expanded = mul;
> + iov->vfs_expanded = mul;
>
> return;
>
> @@ -2916,6 +2914,9 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
> res->flags = 0;
> res->end = res->start - 1;
> }
> +
> + pdev->dev.archdata.iov_data = NULL;
> + kfree(iov);
> }
>
> static void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
> @@ -3321,7 +3322,7 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
> int resno)
> {
> struct pnv_phb *phb = pci_bus_to_pnvhb(pdev->bus);
> - struct pci_dn *pdn = pci_get_pdn(pdev);
> + struct pnv_iov_data *iov = pnv_iov_get(pdev);
> resource_size_t align;
>
> /*
> @@ -3342,12 +3343,21 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
> * M64 segment size if IOV BAR size is less.
> */
> align = pci_iov_resource_size(pdev, resno);
> - if (!pdn->vfs_expanded)
> +
> + /*
> + * iov can be null if we have an SR-IOV device with IOV BAR that can't
> + * be placed in the m64 space (i.e. The BAR is 32bit or non-prefetch).
> + * In that case we don't allow VFs to be enabled so just return the
> + * default alignment.
> + */
> + if (!iov)
> return align;
> - if (pdn->m64_single_mode)
> + if (!iov->vfs_expanded)
> + return align;
> + if (iov->m64_single_mode)
> return max(align, (resource_size_t)phb->ioda.m64_segsize);
>
> - return pdn->vfs_expanded * align;
> + return iov->vfs_expanded * align;
> }
> #endif /* CONFIG_PCI_IOV */
>
> @@ -3545,12 +3555,21 @@ static void pnv_pci_release_device(struct pci_dev *pdev)
> struct pci_dn *pdn = pci_get_pdn(pdev);
> struct pnv_ioda_pe *pe;
>
> + /* The VF PE state is torn down when sriov_disable() is called */
> if (pdev->is_virtfn)
> return;
>
> if (!pdn || pdn->pe_number == IODA_INVALID_PE)
> return;
>
> + /*
> + * FIXME: Try move this to sriov_disable(). It's here since we allocate
> + * the iov state at probe time since we need to fiddle with the IOV
> + * resources.
> + */
> + if (pdev->is_physfn)
> + kfree(pdev->dev.archdata.iov_data);
pdev->dev.archdata.iov_data = NULL just in case if some other device
shutdown code tries accessing it.
> +
> /*
> * PCI hotplug can happen as part of EEH error recovery. The @pdn
> * isn't removed and added afterwards in this scenario. We should
> diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
> index 52dc4d05eaca..0e875f714911 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -168,6 +168,42 @@ struct pnv_phb {
> u8 *diag_data;
> };
>
> +#ifdef CONFIG_PCI_IOV
> +/*
> + * For SR-IOV we want to put each VF's MMIO resource in to a seperate 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;
Can this one be removed from pci_dn now? It looks like it can after
46/46 indeed. And probably others as well as they do not seem to be used
by pseries anyway. Thanks,
> +
> + /* 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;
> +}
> +#endif
> +
> extern struct pci_ops pnv_pci_ops;
>
> void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
>
--
Alexey
More information about the Linuxppc-dev
mailing list