xref: /qemu/include/hw/pci/pcie_sriov.h (revision 21596064081e8d0c0153f68714981c7f0e040973)
17c0fa8dfSKnut Omang /*
27c0fa8dfSKnut Omang  * pcie_sriov.h:
37c0fa8dfSKnut Omang  *
47c0fa8dfSKnut Omang  * Implementation of SR/IOV emulation support.
57c0fa8dfSKnut Omang  *
67c0fa8dfSKnut Omang  * Copyright (c) 2015 Knut Omang <knut.omang@oracle.com>
77c0fa8dfSKnut Omang  *
87c0fa8dfSKnut Omang  * This work is licensed under the terms of the GNU GPL, version 2 or later.
97c0fa8dfSKnut Omang  * See the COPYING file in the top-level directory.
107c0fa8dfSKnut Omang  *
117c0fa8dfSKnut Omang  */
127c0fa8dfSKnut Omang 
137c0fa8dfSKnut Omang #ifndef QEMU_PCIE_SRIOV_H
147c0fa8dfSKnut Omang #define QEMU_PCIE_SRIOV_H
157c0fa8dfSKnut Omang 
16104a2dd6SMarkus Armbruster #include "hw/pci/pci.h"
17104a2dd6SMarkus Armbruster 
18fe5943feSPaolo Bonzini typedef struct PCIESriovPF {
197c0fa8dfSKnut Omang     uint8_t vf_bar_type[PCI_NUM_REGIONS];   /* Store type for each VF bar */
207c0fa8dfSKnut Omang     PCIDevice **vf;     /* Pointer to an array of num_vfs VF devices */
2119e55471SAkihiko Odaki     bool vf_user_created; /* If VFs are created by user */
22fe5943feSPaolo Bonzini } PCIESriovPF;
237c0fa8dfSKnut Omang 
24fe5943feSPaolo Bonzini typedef struct PCIESriovVF {
257c0fa8dfSKnut Omang     PCIDevice *pf;      /* Pointer back to owner physical function */
267c0fa8dfSKnut Omang     uint16_t vf_number; /* Logical VF number of this function */
27fe5943feSPaolo Bonzini } PCIESriovVF;
287c0fa8dfSKnut Omang 
293391d68eSAkihiko Odaki bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
307c0fa8dfSKnut Omang                         const char *vfname, uint16_t vf_dev_id,
317c0fa8dfSKnut Omang                         uint16_t init_vfs, uint16_t total_vfs,
323391d68eSAkihiko Odaki                         uint16_t vf_offset, uint16_t vf_stride,
333391d68eSAkihiko Odaki                         Error **errp);
347c0fa8dfSKnut Omang void pcie_sriov_pf_exit(PCIDevice *dev);
357c0fa8dfSKnut Omang 
367c0fa8dfSKnut Omang /* Set up a VF bar in the SR/IOV bar area */
377c0fa8dfSKnut Omang void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
387c0fa8dfSKnut Omang                                uint8_t type, dma_addr_t size);
397c0fa8dfSKnut Omang 
407c0fa8dfSKnut Omang /* Instantiate a bar for a VF */
417c0fa8dfSKnut Omang void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
427c0fa8dfSKnut Omang                                 MemoryRegion *memory);
437c0fa8dfSKnut Omang 
4419e55471SAkihiko Odaki /**
4519e55471SAkihiko Odaki  * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
46*d0c280d3SAkihiko Odaki  *                                              VFs, adding ARI to PF
4719e55471SAkihiko Odaki  * @dev: A PCIe device being realized.
4819e55471SAkihiko Odaki  * @offset: The offset of the SR-IOV capability.
4919e55471SAkihiko Odaki  * @errp: pointer to Error*, to store an error if it happens.
5019e55471SAkihiko Odaki  *
51*d0c280d3SAkihiko Odaki  * Initializes a PF with user-created VFs, adding the ARI extended capability to
52*d0c280d3SAkihiko Odaki  * the PF. The VFs should call pcie_ari_init() to form an ARI device.
53*d0c280d3SAkihiko Odaki  *
54*d0c280d3SAkihiko Odaki  * Return: The size of added capabilities. 0 if the user did not create VFs.
5519e55471SAkihiko Odaki  *         -1 if failed.
5619e55471SAkihiko Odaki  */
5719e55471SAkihiko Odaki int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
5819e55471SAkihiko Odaki                                                  uint16_t offset,
5919e55471SAkihiko Odaki                                                  Error **errp);
6019e55471SAkihiko Odaki 
6119e55471SAkihiko Odaki bool pcie_sriov_register_device(PCIDevice *dev, Error **errp);
6219e55471SAkihiko Odaki void pcie_sriov_unregister_device(PCIDevice *dev);
6319e55471SAkihiko Odaki 
647c0fa8dfSKnut Omang /*
657c0fa8dfSKnut Omang  * Default (minimal) page size support values
667c0fa8dfSKnut Omang  * as required by the SR/IOV standard:
677c0fa8dfSKnut Omang  * 0x553 << 12 = 0x553000 = 4K + 8K + 64K + 256K + 1M + 4M
687c0fa8dfSKnut Omang  */
697c0fa8dfSKnut Omang #define SRIOV_SUP_PGSIZE_MINREQ 0x553
707c0fa8dfSKnut Omang 
717c0fa8dfSKnut Omang /*
727c0fa8dfSKnut Omang  * Optionally add supported page sizes to the mask of supported page sizes
737c0fa8dfSKnut Omang  * Page size values are interpreted as opt_sup_pgsize << 12.
747c0fa8dfSKnut Omang  */
757c0fa8dfSKnut Omang void pcie_sriov_pf_add_sup_pgsize(PCIDevice *dev, uint16_t opt_sup_pgsize);
767c0fa8dfSKnut Omang 
777c0fa8dfSKnut Omang /* SR/IOV capability config write handler */
787c0fa8dfSKnut Omang void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
797c0fa8dfSKnut Omang                              uint32_t val, int len);
807c0fa8dfSKnut Omang 
81f9efcd47SAkihiko Odaki void pcie_sriov_pf_post_load(PCIDevice *dev);
82f9efcd47SAkihiko Odaki 
83c8bc4db4SAkihiko Odaki /* Reset SR/IOV */
84c8bc4db4SAkihiko Odaki void pcie_sriov_pf_reset(PCIDevice *dev);
857c0fa8dfSKnut Omang 
867c0fa8dfSKnut Omang /* Get logical VF number of a VF - only valid for VFs */
877c0fa8dfSKnut Omang uint16_t pcie_sriov_vf_number(PCIDevice *dev);
887c0fa8dfSKnut Omang 
897c0fa8dfSKnut Omang /*
907c0fa8dfSKnut Omang  * Get the physical function that owns this VF.
917c0fa8dfSKnut Omang  * Returns NULL if dev is not a virtual function
927c0fa8dfSKnut Omang  */
937c0fa8dfSKnut Omang PCIDevice *pcie_sriov_get_pf(PCIDevice *dev);
947c0fa8dfSKnut Omang 
9569387f49SŁukasz Gieryk /*
9669387f49SŁukasz Gieryk  * Get the n-th VF of this physical function - only valid for PF.
9769387f49SŁukasz Gieryk  * Returns NULL if index is invalid
9869387f49SŁukasz Gieryk  */
9969387f49SŁukasz Gieryk PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, int n);
10069387f49SŁukasz Gieryk 
10131180dbdSAkihiko Odaki /* Returns the current number of virtual functions. */
10231180dbdSAkihiko Odaki uint16_t pcie_sriov_num_vfs(PCIDevice *dev);
10331180dbdSAkihiko Odaki 
1047c0fa8dfSKnut Omang #endif /* QEMU_PCIE_SRIOV_H */
105