| 1 | /* |
| 2 | * pcie_sriov.h: |
| 3 | * |
| 4 | * Implementation of SR/IOV emulation support. |
| 5 | * |
| 6 | * Copyright (c) 2015 Knut Omang <knut.omang@oracle.com> |
| 7 | * |
| 8 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 9 | * See the COPYING file in the top-level directory. |
| 10 | * |
| 11 | */ |
| 12 | |
| 13 | #ifndef QEMU_PCIE_SRIOV_H |
| 14 | #define QEMU_PCIE_SRIOV_H |
| 15 | |
| 16 | #include "hw/pci/pci.h" |
| 17 | |
| 18 | typedef struct PCIESriovPF { |
| 19 | uint8_t vf_bar_type[PCI_NUM_REGIONS]; /* Store type for each VF bar */ |
| 20 | PCIDevice **vf; /* Pointer to an array of num_vfs VF devices */ |
| 21 | bool vf_user_created; /* If VFs are created by user */ |
| 22 | } PCIESriovPF; |
| 23 | |
| 24 | typedef struct PCIESriovVF { |
| 25 | PCIDevice *pf; /* Pointer back to owner physical function */ |
| 26 | uint16_t vf_number; /* Logical VF number of this function */ |
| 27 | } PCIESriovVF; |
| 28 | |
| 29 | bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, |
| 30 | const char *vfname, uint16_t vf_dev_id, |
| 31 | uint16_t init_vfs, uint16_t total_vfs, |
| 32 | uint16_t vf_offset, uint16_t vf_stride, |
| 33 | Error **errp); |
| 34 | void pcie_sriov_pf_exit(PCIDevice *dev); |
| 35 | |
| 36 | /* Set up a VF bar in the SR/IOV bar area */ |
| 37 | void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num, |
| 38 | uint8_t type, dma_addr_t size); |
| 39 | |
| 40 | /** |
| 41 | * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created |
| 42 | * VFs, adding ARI to PF |
| 43 | * @dev: A PCIe device being realized. |
| 44 | * @offset: The offset of the SR-IOV capability. |
| 45 | * @errp: pointer to Error*, to store an error if it happens. |
| 46 | * |
| 47 | * Initializes a PF with user-created VFs, adding the ARI extended capability to |
| 48 | * the PF. The VFs should call pcie_ari_init() to form an ARI device. |
| 49 | * |
| 50 | * Return: The size of added capabilities. 0 if the user did not create VFs. |
| 51 | * -1 if failed. |
| 52 | */ |
| 53 | int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev, |
| 54 | uint16_t offset, |
| 55 | Error **errp); |
| 56 | |
| 57 | bool pcie_sriov_register_device(PCIDevice *dev, Error **errp); |
| 58 | void pcie_sriov_unregister_device(PCIDevice *dev); |
| 59 | |
| 60 | /* |
| 61 | * Default (minimal) page size support values |
| 62 | * as required by the SR/IOV standard: |
| 63 | * 0x553 << 12 = 0x553000 = 4K + 8K + 64K + 256K + 1M + 4M |
| 64 | */ |
| 65 | #define SRIOV_SUP_PGSIZE_MINREQ 0x553 |
| 66 | |
| 67 | /* |
| 68 | * Optionally add supported page sizes to the mask of supported page sizes |
| 69 | * Page size values are interpreted as opt_sup_pgsize << 12. |
| 70 | */ |
| 71 | void pcie_sriov_pf_add_sup_pgsize(PCIDevice *dev, uint16_t opt_sup_pgsize); |
| 72 | |
| 73 | /* SR/IOV capability config write handler */ |
| 74 | void pcie_sriov_config_write(PCIDevice *dev, uint32_t address, |
| 75 | uint32_t val, int len); |
| 76 | |
| 77 | void pcie_sriov_pf_post_load(PCIDevice *dev); |
| 78 | |
| 79 | /* Reset SR/IOV */ |
| 80 | void pcie_sriov_pf_reset(PCIDevice *dev); |
| 81 | |
| 82 | /* Get logical VF number of a VF - only valid for VFs */ |
| 83 | uint16_t pcie_sriov_vf_number(PCIDevice *dev); |
| 84 | |
| 85 | /* |
| 86 | * Get the physical function that owns this VF. |
| 87 | * Returns NULL if dev is not a virtual function |
| 88 | */ |
| 89 | PCIDevice *pcie_sriov_get_pf(PCIDevice *dev); |
| 90 | |
| 91 | /* |
| 92 | * Get the n-th VF of this physical function - only valid for PF. |
| 93 | * Returns NULL if index is invalid |
| 94 | */ |
| 95 | PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, int n); |
| 96 | |
| 97 | /* Returns the current number of virtual functions. */ |
| 98 | uint16_t pcie_sriov_num_vfs(PCIDevice *dev); |
| 99 | |
| 100 | #endif /* QEMU_PCIE_SRIOV_H */ |