[U-Boot] [RFC PATCH 08/29] drivers: pci-uclass: add support for Single-Root I/O Virtualizaiton
Simon Glass
sjg at chromium.org
Wed Nov 20 03:00:14 UTC 2019
Hi Suneel,
On Tue, 29 Oct 2019 at 14:08, Suneel Garapati <suneelglinux at gmail.com> wrote:
>
> From: Suneel Garapati <sgarapati at marvell.com>
>
> If SR-IOV capability is present, use it to initialize Virtual function
> (VF) PCI device instances. pci_sriov_init function will read SR-IOV
> registers to create VF devices under the PF PCI device and also bind
> driver if available. This function needs to be invoked from Physical
> function device driver which expects VF device support, creating
> minimal impact on existing framework.
Please expand your abbreviations .
This seems like a nice implementation overall, but it needs a sandbox
test and some documentation.
>
> Signed-off-by: Suneel Garapati <sgarapati at marvell.com>
> ---
> drivers/pci/pci-uclass.c | 113 +++++++++++++++++++++++++++++++++++++++
> include/pci.h | 18 +++++++
> 2 files changed, 131 insertions(+)
>
> diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> index 51f7135723..3be49c7115 100644
> --- a/drivers/pci/pci-uclass.c
> +++ b/drivers/pci/pci-uclass.c
> @@ -1535,6 +1535,119 @@ int dm_pci_flr(struct udevice *dev)
> return 0;
> }
>
is this supported to be exported? It needs a comment.
> +int pci_sriov_init(struct udevice *pdev, int vf_en)
> +{
> + u16 vendor, device;
> + struct udevice *bus;
> + struct udevice *dev;
> + pci_dev_t bdf;
> + u16 ctrl;
> + u16 num_vfs;
> + u16 total_vf;
> + u16 vf_offset;
> + u16 vf_stride;
> + int vf, ret;
> + int pos;
> +
> + pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
> + if (!pos) {
> + printf("Error: SRIOV capability not found\n");
debug()
> + return -ENOENT;
> + }
> +
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_CTRL, &ctrl);
> +
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf);
> + if (vf_en > total_vf)
> + vf_en = total_vf;
> + dm_pci_write_config16(pdev, pos + PCI_SRIOV_NUM_VF, vf_en);
> +
> + ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
> + dm_pci_write_config16(pdev, pos + PCI_SRIOV_CTRL, ctrl);
> +
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_NUM_VF, &num_vfs);
> + if (num_vfs > vf_en)
> + num_vfs = vf_en;
> +
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_OFFSET, &vf_offset);
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_STRIDE, &vf_stride);
> +
> + dm_pci_read_config16(pdev, PCI_VENDOR_ID, &vendor);
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_DID, &device);
> +
> + bdf = dm_pci_get_bdf(pdev);
> +
> + pci_get_bus(PCI_BUS(bdf), &bus);
> +
> + if (!bus)
> + return -ENODEV;
> +
> + bdf += PCI_BDF(0, 0, vf_offset);
> +
> + for (vf = 0; vf < num_vfs; vf++) {
This function is way too long - can you please split?
> + struct pci_child_platdata *pplat;
> + ulong class;
> +
> + pci_bus_read_config(bus, bdf, PCI_CLASS_DEVICE,
> + &class, PCI_SIZE_16);
> +
> + debug("%s: bus %d/%s: found VF %x:%x\n", __func__,
> + bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
> +
> + /* Find this device in the device tree */
> + ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
> +
> + if (ret == -ENODEV) {
> + struct pci_device_id find_id;
> +
> + memset(&find_id, 0, sizeof(find_id));
'\0'
> +
> + find_id.vendor = vendor;
> + find_id.device = device;
> + find_id.class = class;
> +
> + ret = pci_find_and_bind_driver(bus, &find_id,
> + bdf, &dev);
Can you share any code with pci_bind_bus_devices(), perhaps but
pulling part of it into a function?
> +
> + if (ret)
> + return ret;
> + }
> +
> + /* Update the platform data */
> + pplat = dev_get_parent_platdata(dev);
> + pplat->devfn = PCI_MASK_BUS(bdf);
> + pplat->vendor = vendor;
> + pplat->device = device;
> + pplat->class = class;
> + pplat->is_virtfn = true;
> + pplat->pfdev = pdev;
> + pplat->virtid = vf * vf_stride + vf_offset;
> +
> + debug("%s: bus %d/%s: found VF %x:%x %x:%x class %lx id %x\n",
> + __func__, dev->seq, dev->name, PCI_DEV(bdf),
> + PCI_FUNC(bdf), vendor, device, class, pplat->virtid);
> + bdf += PCI_BDF(0, 0, vf_stride);
> + }
> +
> + return 0;
> +}
> +
> +int pci_sriov_get_totalvfs(struct udevice *pdev)
> +{
> + u16 total_vf;
> + int pos;
> +
> + pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
> + if (!pos) {
> + printf("Error: SRIOV capability not found\n");
debug()
> + return -ENOENT;
> + }
> +
> + dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf);
> +
> + return total_vf;
> +}
> +
> UCLASS_DRIVER(pci) = {
> .id = UCLASS_PCI,
> .name = "pci",
> diff --git a/include/pci.h b/include/pci.h
> index 0b14842285..1343d0e9fb 100644
> --- a/include/pci.h
> +++ b/include/pci.h
> @@ -475,6 +475,17 @@
> #define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
> #define PCI_EXP_DEVCTL 8 /* Device Control */
> #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
> +/* Single Root I/O Virtualization Registers */
> +#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */
> +#define PCI_SRIOV_CTRL 0x08 /* SR-IOV Control */
> +#define PCI_SRIOV_CTRL_VFE 0x01 /* VF Enable */
> +#define PCI_SRIOV_CTRL_MSE 0x08 /* VF Memory Space Enable */
> +#define PCI_SRIOV_INITIAL_VF 0x0c /* Initial VFs */
> +#define PCI_SRIOV_TOTAL_VF 0x0e /* Total VFs */
> +#define PCI_SRIOV_NUM_VF 0x10 /* Number of VFs */
> +#define PCI_SRIOV_VF_OFFSET 0x14 /* First VF Offset */
> +#define PCI_SRIOV_VF_STRIDE 0x16 /* Following VF Stride */
> +#define PCI_SRIOV_VF_DID 0x1a /* VF Device ID */
>
> /* Include the ID list */
>
> @@ -868,6 +879,10 @@ struct pci_child_platdata {
> unsigned short vendor;
> unsigned short device;
> unsigned int class;
> +
> + bool is_virtfn;
> + struct udevice *pfdev;
> + int virtid;
Add comments. You can see them above!
> };
>
> /* PCI bus operations */
> @@ -1178,6 +1193,9 @@ int pci_generic_mmap_read_config(
> ulong *valuep,
> enum pci_size_t size);
>
> +int pci_sriov_init(struct udevice *pdev, int vf_en);
> +int pci_sriov_get_totalvfs(struct udevice *pdev);
Comments!
> +
> #ifdef CONFIG_DM_PCI_COMPAT
> /* Compatibility with old naming */
> static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
> --
> 2.23.0
>
Regards,
Simon
More information about the U-Boot
mailing list