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


Reply via email to