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