From: Dimitri Daskalakis <[email protected]> Define the PCIe SIOV extended capability registers per the PCIe 7.0 spec, and introduce the kernel-internal data structures needed to track SIOV state on a Physical Function. PCI-SIG members can access the spec here https://members.pcisig.com/wg/PCI-SIG/document/previewpdf/22464.
The PCI_SIOV kconfig selects PCI_ATS rather than attempting to decouple the sriov/physfn union within struct pci_dev from CONFIG_PCI_ATS. If desired this can be done in the future, since ATS is optional for SR-IOV and SIOV. Inspired by struct pci_sriov, struct pci_siov records the capability position, total SDI count, routing ID offset/stride, and driver-configurable limits. Add an is_siov bit to struct pci_dev along with helpers to identify SIOV PFs/VFs. Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Dimitri Daskalakis <[email protected]> --- drivers/pci/Kconfig | 11 +++++++++++ drivers/pci/pci.h | 13 +++++++++++++ include/linux/pci.h | 16 +++++++++++++++- include/uapi/linux/pci_regs.h | 12 +++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 33c88432b728..930231835c40 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -164,6 +164,17 @@ config PCI_IOV If unsure, say N. +config PCI_SIOV + bool "PCI Scalable IOV support" + select PCI_ATS + help + Scalable I/O Virtualization is a PCIe feature that allows devices + to expose lightweight Scalable Device Interfaces (SDIs). Unlike + SR-IOV Virtual Functions, SDIs have no config space or BARs and + rely on software to compose the control path. + + If unsure, say N. + config PCI_NPEM bool "Native PCIe Enclosure Management" depends on LEDS_CLASS=y diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 45411960fd2e..fd7c04e26c16 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -683,6 +683,19 @@ struct pci_sriov { bool drivers_autoprobe; /* Auto probing of VFs by driver */ }; +/* Scalable I/O Virtualization */ +struct pci_siov { + struct pci_dev *self; /* This PF */ + u32 cap; /* SIOV Capabilities */ + u16 pos; /* Capability position */ + u16 total_SDIs; /* Total SDIs associated with the PF */ + u16 num_SDIs; /* Number of SDIs currently enabled */ + u16 offset; /* First SDI Routing ID offset */ + u16 stride; /* Following SDI stride */ + u16 driver_max_SDIs;/* Max num SDIs driver supports */ + u8 max_SDI_buses; /* Max buses consumed by SDIs */ +}; + #ifdef CONFIG_PCI_DOE void pci_doe_init(struct pci_dev *pdev); void pci_doe_destroy(struct pci_dev *pdev); diff --git a/include/linux/pci.h b/include/linux/pci.h index ca84f66425b2..eba562474017 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -480,6 +480,7 @@ struct pci_dev { unsigned int is_physfn:1; unsigned int is_virtfn:1; unsigned int is_sriov:1; /* SR-IOV is enabled on this device (PF or VF) */ + unsigned int is_siov:1; /* SIOV is enabled on this device (PF or VF/SDI) */ unsigned int is_hotplug_bridge:1; unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ @@ -549,6 +550,9 @@ struct pci_dev { u16 ats_cap; /* ATS Capability offset */ u8 ats_stu; /* ATS Smallest Translation Unit */ #endif +#ifdef CONFIG_PCI_SIOV + struct pci_siov *siov; /* PF: Scalable IOV info */ +#endif #ifdef CONFIG_PCI_PRI u16 pri_cap; /* PRI Capability offset */ u32 pri_reqs_alloc; /* Number of PRI requests allocated */ @@ -598,7 +602,7 @@ struct pci_dev { static inline struct pci_dev *pci_physfn(struct pci_dev *dev) { -#ifdef CONFIG_PCI_IOV +#if defined(CONFIG_PCI_IOV) || defined(CONFIG_PCI_SIOV) if (dev->is_virtfn) dev = dev->physfn; #endif @@ -615,6 +619,16 @@ static inline bool pci_is_sriov_virtfn(const struct pci_dev *dev) return dev->is_virtfn && dev->is_sriov; } +static inline bool pci_is_siov_physfn(const struct pci_dev *dev) +{ + return dev->is_physfn && dev->is_siov; +} + +static inline bool pci_is_siov_virtfn(const struct pci_dev *dev) +{ + return dev->is_virtfn && dev->is_siov; +} + struct pci_dev *pci_alloc_dev(struct pci_bus *bus); #define to_pci_dev(n) container_of(n, struct pci_dev, dev) diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 14f634ab9350..0f81c8c72b05 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -763,7 +763,8 @@ #define PCI_EXT_CAP_ID_DEV3 0x2F /* Device 3 Capability/Control/Status */ #define PCI_EXT_CAP_ID_IDE 0x30 /* Integrity and Data Encryption */ #define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */ -#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT +#define PCI_EXT_CAP_ID_SIOV 0x38 /* Scalable I/O Virtualization */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_SIOV #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 @@ -1005,6 +1006,15 @@ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ #define PCI_EXT_CAP_SRIOV_SIZEOF 0x40 +/* Scalable I/O Virtualization */ +#define PCI_SIOV_CAP 0x04 /* SIOV Capabilities */ +#define PCI_SIOV_TOTAL_SDI 0x08 /* Total SDIs */ +#define PCI_SIOV_STATUS 0x0B /* SIOV Status */ +#define PCI_SIOV_STATUS_ENABLED 0x01 /* At least one SDI is enabled */ +#define PCI_SIOV_SDI_OFFSET 0x0C /* First SDI Offset */ +#define PCI_SIOV_SDI_STRIDE 0x0E /* SDI Stride */ +#define PCI_EXT_CAP_SIOV_SIZEOF 0x10 + #define PCI_LTR_MAX_SNOOP_LAT 0x4 #define PCI_LTR_MAX_NOSNOOP_LAT 0x6 #define PCI_LTR_VALUE_MASK 0x000003ff -- 2.52.0
