vmkdrivers/BLD/build/HEADERS/vmkapi-current-all-public/vmkernel64/release/device/vmkapi_pci.h
2015-10-23 18:26:03 -04:00

701 lines
26 KiB
C

/* **********************************************************
* Copyright 1998 - 2013 VMware, Inc. All rights reserved.
* **********************************************************/
/*
* @VMKAPIMOD_LICENSE@
*/
/*
* Please consult with the VMKernel hardware and core teams before making any
* binary incompatible changes to this file!
*/
/*
***********************************************************************
* PCI */ /**
* \addtogroup Device
* @{
* \defgroup PCI PCI
* @{
***********************************************************************
*/
#ifndef _VMKAPI_PCI_H_
#define _VMKAPI_PCI_H_
/** \cond never */
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
#error This vmkapi file should never be included directly but only via vmkapi.h
#endif
/** \endcond never */
#include "device/vmkapi_vector.h"
#define VMK_PCI_BUS_NAME "pci"
/** \brief Maximum number of characters in a PCI device name. */
#define VMK_PCI_DEVICE_NAME_LENGTH 32
/** \brief Per-system max for segments */
#define VMK_PCI_NUM_SEGS 256
/** \brief Per-system max for busses */
#define VMK_PCI_NUM_BUSES 256
/** \brief Per-bus max for slots */
#define VMK_PCI_NUM_SLOTS 32
/** \brief Per-slot max for functions */
#define VMK_PCI_NUM_FUNCS 8
/** \brief Per-device max for BARs */
#define VMK_PCI_NUM_BARS 6
/** \brief Per-device max for BARs on a bridge */
#define VMK_PCI_NUM_BARS_BRIDGE 2
/**
* \brief PCI BAR flags.
*/
typedef enum vmk_PCIBARFlags {
VMK_PCI_BAR_FLAGS_IO = 0x1,
VMK_PCI_BAR_FLAGS_MEM_64_BITS = 0x4,
VMK_PCI_BAR_FLAGS_MEM_PREFETCHABLE = 0x8,
VMK_PCI_BAR_FLAGS_IO_MASK = 0x3,
VMK_PCI_BAR_FLAGS_MEM_MASK = 0xF,
} vmk_PCIBARFlags;
/**
* \brief PCI device identifier.
*
*/
typedef struct vmk_PCIDeviceID {
vmk_uint16 vendorID;
vmk_uint16 deviceID;
vmk_uint16 subVendorID;
vmk_uint16 subDeviceID;
vmk_uint16 classCode;
vmk_uint16 progIFRevID;
} vmk_PCIDeviceID;
/**
* \brief PCI device Address (SBDF).
*
*/
typedef struct vmk_PCIDeviceAddr {
vmk_uint16 seg;
vmk_uint8 bus;
vmk_uint8 dev:5;
vmk_uint8 fn:3;
} vmk_PCIDeviceAddr;
/**
* \brief PCI device resource.
*
*/
typedef struct vmk_PCIResource {
/** \brief Resource's physical address. */
vmk_MA start;
/** \brief Resource size in bytes. */
vmk_ByteCount size;
/** \brief Resource flags. */
vmk_uint64 flags;
} vmk_PCIResource;
/**
* \brief Configuration space access types
*/
typedef enum vmk_PCIConfigAccess {
VMK_PCI_CONFIG_ACCESS_8 = 1,
VMK_PCI_CONFIG_ACCESS_16 = 2,
VMK_PCI_CONFIG_ACCESS_32 = 4
} vmk_PCIConfigAccess;
/*
***********************************************************************
* vmk_PCIRemoveVF -- */ /**
*
* \ingroup PCI
* \brief Remove a PCI virtual function (VF) device.
*
* Physical function (PF) driver should carry out any operations
* required for the removal of a virtual function device, and
* unregister the virtual function device using vmk_PCIUnregisterVF().
*
* \param[in] vf Handle to PCI VF to be removed.
*
* \retval VMK_OK Success
*
***********************************************************************
*/
typedef VMK_ReturnStatus (*vmk_PCIRemoveVF)(vmk_PCIDevice vf);
/**
* \brief PCI virtual function (VF) device operations.
*/
typedef struct {
/** \brief Remove a PCI virtual function from the system. */
vmk_PCIRemoveVF removeVF;
} vmk_PCIVFDeviceOps;
/**
***********************************************************************
* vmk_PCIQueryDeviceID -- */ /**
*
* \ingroup PCI
* \brief Query PCI Device's identifier information.
*
* Upon successful completion, devID structure is filled with the
* identifier information.
*
* \param[in] pciDevice Pointer to PCI device handle.
* \param[out] devID Pointer to PCI Device ID struct.
*
* \retval VMK_BAD_PARAM pciDevice or devID is invalid.
* \retval VMK_OK Query successfully processed.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIQueryDeviceID(vmk_PCIDevice pciDevice,
vmk_PCIDeviceID *devID);
/**
***********************************************************************
* vmk_PCIQueryDeviceAddr -- */ /**
*
* \ingroup PCI
* \brief Query PCI Device's Address (SBDF) information.
*
* Upon successful operation, sbdf struct is filled with device's
* seg, bus, dev, fn information.
*
* \param[in] pciDevice Pointer to PCI device handle.
* \param[out] sbdf Pointer to PCI Device Addr struct.
*
* \retval VMK_BAD_PARAM pciDevice or sbdf is invalid.
* \retval VMK_OK Query successfully processed.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIQueryDeviceAddr(vmk_PCIDevice pciDevice,
vmk_PCIDeviceAddr *sbdf);
/**
***********************************************************************
* vmk_PCIQueryIOResources -- */ /**
*
* \ingroup PCI
* \brief Query PCI Device's BAR resources information.
*
* Upon successful completion, resources array is filled with device's
* first numBars BARs [0 - numBars) information. The resources array
* passed in should be able to hold numBars resources.
*
* \param[in] pciDevice Pointer to PCI device handle.
* \param[in] numBars Number of resources queried.
* \param[out] resources Pointer to PCI resources array.
*
* \retval VMK_BAD_PARAM pciDevice or resources is invalid.
* \retval VMK_BAD_PARAM numBars is greater than VMK_PCI_NUM_BARS
* \retval VMK_OK Query successfully processed.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIQueryIOResources(vmk_PCIDevice pciDevice,
vmk_uint8 numBars,
vmk_PCIResource resources[]);
/*
***********************************************************************
* vmk_PCIFindCapability -- */ /**
*
* \ingroup PCI
* \brief Returns the offset of the capability in device's config space.
*
* \param[in] device PCI device handle
* \param[in] capID Capability ID of interest
* \param[out] capOffset Pointer to the capability offset
*
* \retval VMK_BAD_PARAM If capOffset is NULL or device handle is invalid
* \retval VMK_NOT_FOUND capability is not found
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIFindCapability(vmk_PCIDevice device,
vmk_uint8 capID,
vmk_uint16 *capOffset);
/*
***********************************************************************
* vmk_PCIReadConfig -- */ /**
*
* \ingroup PCI
* \brief Read config space of device at offset.
*
* \param[in] moduleID Module performing the config read.
* \param[in] device PCI device handle.
* \param[in] accessType Access 1, 2 or 4 bytes.
* \param[in] offset Offset to read.
* \param[out] data Pointer to the data read.
*
* \note Offset is expected to meet the alignment requirements of the
* specified access type.
*
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
* \retval VMK_BAD_PARAM Data pointer is NULL.
* \retval VMK_BAD_PARAM Offset is not aligned for the access type.
* \retval VMK_BAD_PARAM AccessType is not a valid access type.
* \retval VMK_NO_PERMISSION Device is not owned by module.
* \retval VMK_LIMIT_EXCEEDED Offset is beyond available config space.
* \retval VMK_FAILURE Failure to access config space.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIReadConfig(vmk_ModuleID moduleID,
vmk_PCIDevice device,
vmk_PCIConfigAccess accessType,
vmk_uint16 offset,
vmk_uint32 *data);
/*
***********************************************************************
* vmk_PCIWriteConfig -- */ /**
*
* \ingroup PCI
* \brief Write data to config space of device at offset.
*
* \param[in] moduleID Module performing the config write.
* \param[in] device PCI device handle.
* \param[in] accessType Access 1, 2 or 4 bytes.
* \param[in] offset Offset to write at.
* \param[in] data Data to write.
*
* \note Offset is expected to meet the alignment requirements of the
* specified access type.
*
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
* \retval VMK_BAD_PARAM Offset is not aligned for the access type.
* \retval VMK_BAD_PARAM AccessType is not a valid access type.
* \retval VMK_NO_PERMISSION Device is not owned by module.
* \retval VMK_LIMIT_EXCEEDED Offset is beyond available config space.
* \retval VMK_FAILURE Failure to access config space.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIWriteConfig(vmk_ModuleID moduleID,
vmk_PCIDevice device,
vmk_PCIConfigAccess accessType,
vmk_uint16 offset,
vmk_uint32 data);
/*
***********************************************************************
* vmk_PCIMapIOResource -- */ /**
*
* \ingroup PCI
* \brief Reserve and map PCI IO/Memory space described by pciBar.
*
* Reserves the specified BAR with resource manager and maps the memory
* described by pciBar to a virtual address.
*
* \param[in] moduleID Module requesting the resource.
* \param[in] device PCI device handle.
* \param[in] pciBar PCI bar to map, must be [0 - 5].
* \param[out] reservation IOReservation handle. Only necessary for
* VMK_PCI_BAR_FLAGS_IO type BARs.
* \param[out] mappedAddress Pointer to hold the virtual address of
* the mapping.
*
* \retval VMK_BAD_PARAM Device handle is NULL/invalid
* \retval VMK_BAD_PARAM PciBar is invalid
* \retval VMK_BAD_PARAM reservation is NULL for PIO BAR
* \retval VMK_BAD_PARAM MappedAddres is NULL
* \retval VMK_NO_RESOURCES Resource is not owned by device
* \retval VMK_NO_PERMISSION Device is not owned by module
* \retval VMK_BAD_PARAM PciBar is 2nd half of 64-bit MMIO BAR
* \retval VMK_BAD_PARAM PciBar addr/size too big for 32-bit MPN
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIMapIOResource(vmk_ModuleID moduleID,
vmk_PCIDevice device,
vmk_uint8 pciBar,
vmk_IOReservation *reservation,
vmk_VA *mappedAddress);
/*
***********************************************************************
* vmk_PCIUnmapIOResource -- */ /**
*
* \ingroup PCI
* \brief Unmap and release the established PCI IO/Memory mapping.
*
* Upon successful return from the call, the mapping is no longer valid.
*
* \param[in] moduleID Module requested the resource.
* \param[in] device PCI device handle.
* \param[in] pciBar PCI bar to unmap.
*
* \retval VMK_BAD_PARAM Device handle is NULL/invalid
* \retval VMK_BAD_PARAM PciBar is invalid
* \retval VMK_BAD_PARAM Resource is not mapped
* \retval VMK_NO_PERMISSION Device is not owned by module
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIUnmapIOResource(vmk_ModuleID moduleID,
vmk_PCIDevice device,
vmk_uint8 pciBar);
/**
* Interrupt related functions.
*
* Driver should first allocate interrupt(s), register and enable the
* interrupt(s).
*/
/*
***********************************************************************
* vmk_PCIAllocIntrCookie -- */ /**
*
* \ingroup PCI
* \brief Allocate interrupt resources for the specified device.
*
* On successful return, intrArray will contain the vmk_IntrCookie(s)
* representing the allocated interrupt resources. numIntrsAlloced
* will contain the number of interrupts actually allocated.
*
* \note If type is VMK_PCI_INTERRUPT_TYPE_LEGACY or type is
* VMK_PCI_INTERRUPT_TYPE_MSI then numIntrsDesired and
* numIntrsRequired must both be set to 1.
* \note The caller must provide memory for numIntrsDesired
* vmk_IntrCookie(s) in the space referenced by intrArray.
* \note The caller can specify the index into MSIX table for the
* desired interrupts using indexAarray. indexArray can be NULL
* if the caller does not care. If non-NULL, it should specify
* index for numIntrDesired entries, and intrArray is filled
* with allocated interrupt for requested index values.
*
* \param[in] moduleID Module allocating the interrupts.
* \param[in] device PCI device handle.
* \param[in] type Interrupt type.
* \param[in] numIntrsDesired Number of interrupts desired.
* \param[in] numIntrsRequired Number of interrupts required.
* \param[in] indexArray Array of MSIX table index.
* \param[out] intrArray Array of interrupts allocated.
* \param[out] numIntrsAlloced Number of interrupts allocated.
*
* \retval VMK_BAD_PARAM props argument is NULL.
* \retval VMK_BAD_PARAM Device handle is invalid/NULL.
* \retval VMK_BAD_PARAM Device is not interruptive.
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_LEGACY
* the ioapic pin the device is connected
* to is not described in interrupt
* routing tables.
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_LEGACY
* or VMK_INTERRUPT_TYPE_PCI_MSI and
* numIntrsDesired or numIntrsRequired
* is not equal to 1.
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_MSIX and
* numIntrsAlloced is NULL.
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_MSIX and
* numIntrsRequired > numIntrsDesired
* \retval VMK_BAD_PARAM All other mal-formed props.
* \retval VMK_NO_MEMORY Internal memory allocation failure
* \retval VMK_NOT_SUPPORTED Device/platform doesn't support MSI or
* MSIX if request is for MSI or MSIX type
* \retval VMK_NO_PERMISSION Device is not owned by module
* \retval VMK_IO_ERROR PCI Bus error, probably device is
* broken or unplugged
* \retval VMK_NO_RESOURCES For MSIX type, the number of interrupts
* available is less than numIntrsRequired.
* \retval VMK_FAILIURE All other errors.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIAllocIntrCookie(vmk_ModuleID moduleID,
vmk_PCIDevice device,
vmk_PCIInterruptType type,
vmk_uint32 numIntrsDesired,
vmk_uint32 numIntrsRequired,
vmk_uint16 *indexArray,
vmk_IntrCookie *intrArray,
vmk_uint32 *numIntrsAlloced);
/*
***********************************************************************
* vmk_PCIFreeIntrCookie -- */ /**
*
* \ingroup PCI
* \brief Free all interrupts that were previously allocated by a call
* to vmk_PCIAllocIntrCookie().
*
* \param[in] moduleID Module that allocated the interrupts
* \param[in] device PCI device handle
*
* \retval VMK_BAD_PARAM Module ID is invalid.
* \retval VMK_BAD_PARAM Device handle is invalid/NULL.
* \retval VMK_NO_PERMISSION Device is not owned by module.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_PCIFreeIntrCookie(vmk_ModuleID moduleID,
vmk_PCIDevice device);
/*
***********************************************************************
* vmk_PCIEnableVFs -- */ /**
*
* \ingroup PCI
* \brief Enable virtual functions in an SR-IOV physical function.
*
* numVFs is the number of virtual functions to be enabled. Setting it to
* zero requests that all virtual functions (VFs) under the given physical
* function (PF) be enabled. The actual number of VFs successfully enabled
* is returned in numVFs upon success.
*
* \note For a native PF driver, this function must be called from the
* driver's vmk_DriverAttachDevice() callback. This will ensure VFs are
* enabled before the driver receives the vmk_DriverScanDevice() callback,
* and also prevent VFs from being re-enabled if the PF is quiesced
* and re-started.
*
* \note This function creates a vmk_PCIDevice handle for each VF. The
* handle of each VF can be retrieved via the function
* vmk_PCIGetVFPCIDevice().
*
* \param[in] pf PCI device handle of the SR-IOV PF.
* \param[in,out] numVFs Number of VFs to enable/enabled.
*
* \retval VMK_BAD_PARAM Device handle is invalid or device does not exist.
* \retval VMK_FAILURE Cannot enable virtual functions.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIEnableVFs(vmk_PCIDevice pf,
vmk_uint16 *numVFs);
/*
***********************************************************************
* vmk_PCIDisableVFs -- */ /**
*
* \ingroup PCI
* \brief Disable all virtual functions in an SR-IOV physical function.
*
* \note For a native PF driver, this function must be called from the
* driver's vmk_DriverDetachDevice() callback. This will ensure that
* all virtual functions (VFs) being disabled have been un-registered
* with the vmkkernel's device layer (i.e., unregistration occurs in the
* PF driver's VF remove callback which occurs prior to
* vmkDriverDetachDevice()). In addition, this will also prevent VFs from
* being disabled if the PF is quiesced.
*
* \param[in] pf PCI device handle of physical function (PF).
*
* \retval VMK_BAD_PARAM Device handle is invalid or device does not exist.
* \retval VMK_FAILURE Device is not in SR-IOV mode.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIDisableVFs(vmk_PCIDevice pf);
/*
***********************************************************************
* vmk_PCIGetVFPCIDevice -- */ /**
*
* \ingroup PCI
* \brief Retrieves the PCI device handle of a virtual function (VF).
*
* \note This function should only be called on enabled VFs (see
* vmk_PCIEnableVF()).
*
* \param[in] pf PCI device handle of the parent physical function.
* \param[in] vfIndex Index of the virtual function.
* \param[out] vf PCI device handle of the requested virtual function.
*
* \retval VMK_BAD_PARAM PF device handle is invalid or device does not exist.
* \retval VMK_BAD_PARAM VF device handle argument is NULL.
* \retval VMK_NOT_FOUND VF doesn't exist.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIGetVFPCIDevice(vmk_PCIDevice pf,
vmk_uint16 vfIndex,
vmk_PCIDevice *vf);
/*
***********************************************************************
* vmk_PCIGetPFPCIDevice -- */ /**
*
* \ingroup PCI
* \brief Retrieve the PCI device handle of a PF, given the VF handle.
*
* \param[in] vf PCI device handle of the virtual function.
* \param[out] pf PCI device handle of the parent physical function.
*
* \retval VMK_BAD_PARAM VF device handle is invalid or device does not exist.
* \retval VMK_BAD_PARAM PF device handle argument is NULL.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIGetPFPCIDevice(vmk_PCIDevice vf, vmk_PCIDevice *pf);
/*
************************************************************************
* vmk_PCIRegisterVF -- */ /**
*
* \ingroup PCI
* \brief Register virtual functions with the vmkernel's device layer.
*
* The devOps parameter is the vmk_DeviceOps structure associated with the
* registered virtual function (VF).
*
* \note This function is meant to be used by native PF drivers only.
* Since this function registers a VF with the vmkernel's device layer,
* all restrictions associated with device registration apply.
*
* \note Before this call returns, the vmkernel's device layer may attach
* the VF to a driver.
*
* \param[in] vf PCI device handle of the VF to be registered.
* \param[in] pf PCI device handle of the parent PF.
* \param[in] pfDriverHandle PF driver handle.
* \param[in] vfDevOps Device operations associated with a registered VF.
*
* \retval VMK_BAD_PARAM VF device handle is invalid.
* \retval VMK_BAD_PARAM PF device handle is invalid.
* \retval VMK_FAILURE VF registration failed.
*
************************************************************************
*/
VMK_ReturnStatus
vmk_PCIRegisterVF(vmk_PCIDevice vf,
vmk_PCIDevice pf,
vmk_Driver pfDriverHandle,
vmk_PCIVFDeviceOps *vfDevOps);
/*
************************************************************************
* vmk_PCIUnregisterVF -- */ /**
*
* \ingroup PCI
* \brief Unregister a virtual function from the vmkernel's device layer.
*
* \note Since this function unregisters a virtual function (VF) with the
* vmkernel's device layer, all restrictions associated with device
* unregistration apply (unregistration of the VF must be done
* by the physical function driver from the vmk_DeviceRemove function in the
* vmk_DeviceOps passed during VF registration).
*
* \param[in] vf PCI device handle of the VF to be unregistered.
*
* \retval VMK_BAD_PARAM VF device handle is invalid.
* \retval VMK_FAILURE VF unregistration failed.
*
*************************************************************************
*/
VMK_ReturnStatus
vmk_PCIUnregisterVF(vmk_PCIDevice vf);
/*
*************************************************************************
* vmk_PCISetVFPrivateData -- */ /**
*
* \ingroup PCI
* \brief Associate private data with a virtual function.
*
* Associates a pointer to the given user-defined private data with the
* given virtual function (VF). The pointer may retrieved via the
* function vmk_PCIGetVFPrivateData(). This provides a mechanism by which
* vmkernel components, typically a PF driver and a VF driver, can exchange
* private data.
*
* \param[in] vf PCI device handle of the VF.
* \param[in] privateData User-defined private data.
*
* \retval VMK_BAD_PARAM VF device handle is invalid.
*
************************************************************************
*/
VMK_ReturnStatus
vmk_PCISetVFPrivateData(vmk_PCIDevice vf,
vmk_AddrCookie privateData);
/*
*************************************************************************
* vmk_PCIGetVFPrivateData -- */ /**
*
* \ingroup PCI
* \brief Retrieve private data associated with a virtual function.
*
* Retrieves a pointer to the user-defined private data associated with
* the given virtual function (VF). See the description of
* vmk_PCISetVFPrivateData() for further details.
*
* \param[in] vf PCI device handle of the VF.
* \param[out] privateData User-defined private data.
*
* \retval VMK_BAD_PARAM VF device handle is invalid.
* \retval VMK_BAD_PARAM privateData pointer is NULL.
*
************************************************************************
*/
VMK_ReturnStatus
vmk_PCIGetVFPrivateData(vmk_PCIDevice vf,
vmk_AddrCookie *privateData);
/*
***********************************************************************
* vmk_PCIEnablePME -- */ /**
*
* \ingroup PCI
* \brief Enable PME# generation.
*
* Enable PME# generation if the device is capable of asserting
* the PME# signal from any of the power states.
*
* \param[in] moduleID Module requesting the operation.
* \param[in] device PCI device handle.
*
* \retval VMK_BAD_PARAM Module ID is invalid.
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
* \retval VMK_NO_PERMISSION Device is not owned by module.
* \retval VMK_NOT_SUPPORTED Device has no PM capability.
* \retval VMK_NOT_SUPPORTED Device doesn't support PME# generation
* from any power state.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIEnablePME(vmk_ModuleID moduleID,
vmk_PCIDevice device);
/*
***********************************************************************
* vmk_PCIDisablePME -- */ /**
*
* \ingroup PCI
* \brief Disable PME# generation.
*
* Disable PME# generation if the device is capable of asserting
* the PME# signal from any of the power states.
*
* \param[in] moduleID Module requesting the operation.
* \param[in] device PCI device handle.
*
* \retval VMK_BAD_PARAM Module ID is invalid.
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
* \retval VMK_NO_PERMISSION Device is not owned by module.
* \retval VMK_NOT_SUPPORTED Device has no PM capability.
* \retval VMK_NOT_SUPPORTED Device doesn't support PME# generation
* from any power state.
*
***********************************************************************
*/
VMK_ReturnStatus
vmk_PCIDisablePME(vmk_ModuleID moduleID,
vmk_PCIDevice device);
#endif /* _VMKAPI_PCI_H_ */
/** @} */
/** @} */