public inbox for linux-cxl@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support.
@ 2026-02-04 17:32 ` Jonathan Cameron
  2026-02-04 17:32   ` [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines Jonathan Cameron
                     ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-04 17:32 UTC (permalink / raw)
  To: Michael Tsirkin, qemu-devel, Arpit Kumar
  Cc: linuxarm, linux-cxl, Ravi Shankar, Marcel Apfelbaum, Michael Roth

Changes since v4:
https://lore.kernel.org/qemu-devel/20250916080736.1266083-1-arpit1.kumar@samsung.com/
- Dropped initial refactor. Reason being that it is not static enough
  for caching at boot to be appropriate.  Kept the spec update part
  of this.
- Added a patch to make sure the new flip mode stuff is reported in
  the Get Physical Port State command.
- Rebased Arpit's Physical Control Control FMAPI Command given drop
  of the major refactor from v4 patch 1.

I had taken this into my cxl staging tree thinking it only needed a few
minor tweaks.  Then whilst testing I realized it didn't work with hotplug
and that made me consider if Arpit's original approach made sense.

So this is my proposal on how to take this forwards. Note that this is
not ready for merge (probably) just yet as I'd like Arpit to take a
look at the changes.  I went through a version that had major refactors
to push the logic of building the records to the ports themselves, but
in the end don't think that brings enough benefits for the complexity.

Based on:
https://lore.kernel.org/qemu-devel/20260204170936.43959-1-Jonathan.Cameron@huawei.com/T/#t
(with all it's precursors, though hopefully they will all be in Michael's
next pull request)

I'll note this is an enormous foot gun as it lets you effectively trigger
surprise device resets.  However, it's only accessible if you are using
a configuration with the fabric management parts of the CXL emulation.
For now that is a switch-cci (MCTP over USB support is near the top
of my list of things to get ready for upstram.  I tested this with a
custom driver and if nothing else it exposed some gaps in Linux's
ability to rescan PCI buses after a perst event (even with drivers
unbound etc to make it safe).

Original cover letter:

This patch series refactor existing support for Identify Switch Device
and Get Physical Port State by utilizing physical ports (USP & DSP)
information stored during enumeration.

Additionally, it introduces new support for Physical Port Control
of Physical Switch Command Set as per CXL spec r3.2 Section 7.6.7.1.3.
It primarily constitutes two logic:
    -Assert-Deassert PERST: Assert PERST involves physical port to be in
     hold reset phase for minimum 100ms. No other physical port control
     request are entertained until Deassert PERST command for the given
     port is issued.
    -Reset PPB: cold reset of physical port (completing enter->hold->exit
     phases).

Tested using libcxl-mi interface[1]:
All active ports and all opcodes per active port is tested. Also, tested
against possible edge cases manually since the interface currently dosen't
support run time input.

Typical Qemu topology
(1 USP + 3 DSP's in a switch with 2 CXLType3 devices connected to the 2 DSP's):
FM="-object memory-backend-file,id=cxl-mem1,mem-path=$TMP_DIR/t3_cxl1.raw,size=256M \
    -object memory-backend-file,id=cxl-lsa1,mem-path=$TMP_DIR/t3_lsa1.raw,size=1M \
    -object memory-backend-file,id=cxl-mem2,mem-path=$TMP_DIR/t3_cxl2.raw,size=512M \
    -object memory-backend-file,id=cxl-lsa2,mem-path=$TMP_DIR/t3_lsa2.raw,size=512M \
    -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1,hdm_for_passthrough=true \
    -device cxl-rp,port=0,bus=cxl.1,id=cxl_rp_port0,chassis=0,slot=2 \
    -device cxl-upstream,port=2,sn=1234,bus=cxl_rp_port0,id=us0,addr=0.0,multifunction=on, \
    -device cxl-switch-mailbox-cci,bus=cxl_rp_port0,addr=0.1,target=us0 \
    -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
    -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
    -device cxl-downstream,port=3,bus=us0,id=swport2,chassis=0,slot=6 \
    -device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 \
    -device cxl-type3,bus=swport2,memdev=cxl-mem2,id=cxl-pmem2,lsa=cxl-lsa2,sn=4 \
    -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \
    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1 \
    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem2 \
    -device virtio-rng-pci,bus=swport1"

Tested multiple Qemu topologies:
        -without any devices connected to downstream ports.
        -with virtio-rng-pci devices connected to downstream ports.
        -with CXLType3 devices connected to downstream ports.
        -with different unique values of ports (both upstream and downstream).

Changes from v3 (https://lore.kernel.org/qemu-devel/20250909160316.00000190@huawei.com/T/):
        -Namespaced the defines with cleaner prefix for Get Physical Port State 
         Port Information Block members.
        -switch CCI implementation instead of switch FM interface as per
         Jonathan's review comments, hence moved perst members initializations
         from: cxl_initialize_usp_mctpcci() -> cxl_initialize_mailbox_swcci().

[1] https://github.com/computexpresslink/libcxlmi/commit/35fe68bd9a31469f832a87694d7b18d2d50be5b8


Arpit Kumar (2):
  hw/cxl: Physical Port Info FMAPI - update to current spec and add
    defines.
  hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)

Jonathan Cameron (1):
  hw/cxl: Get Physical Port State - update for PCIe flit mode

 include/hw/cxl/cxl_port.h                   |  73 ++++++++
 include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
 include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
 hw/cxl/cxl-mailbox-utils.c                  | 183 ++++++++++++++++++--
 hw/pci-bridge/cxl_downstream.c              |   9 +
 hw/pci-bridge/cxl_upstream.c                |   1 +
 6 files changed, 268 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/cxl/cxl_port.h
 create mode 100644 include/hw/pci-bridge/cxl_downstream_port.h

-- 
2.51.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines.
  2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
@ 2026-02-04 17:32   ` Jonathan Cameron
  2026-02-12 15:22     ` Arpit Kumar
  2026-02-04 17:32   ` [PATCH qemu v5 2/3] hw/cxl: Get Physical Port State - update for PCIe flit mode Jonathan Cameron
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-04 17:32 UTC (permalink / raw)
  To: Michael Tsirkin, qemu-devel, Arpit Kumar
  Cc: linuxarm, linux-cxl, Ravi Shankar, Marcel Apfelbaum, Michael Roth

From: Arpit Kumar <arpit1.kumar@samsung.com>

Add a new cxl/cxl_ports.h header for field definitions related only to port
commands. Bring field naming up to date with spec as 'version' bitmasks
have been replaced with bitmasks of the specific features.

Fix a small issue where a reserved value for USP was set to 2 rather
than 0.

Signed-off-by: Arpit Kumar <arpit1.kumar@samsung.com>
Co-developed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@huawei.com>

---
This is effectively lifted out of Arpit's orginal rework.
Arpit please confirm you are fine with keeping authorship on this one.
---
 include/hw/cxl/cxl_port.h  | 53 ++++++++++++++++++++++++++++++++++++++
 hw/cxl/cxl-mailbox-utils.c | 31 ++++++++++++++--------
 2 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/include/hw/cxl/cxl_port.h b/include/hw/cxl/cxl_port.h
new file mode 100644
index 000000000000..04db60f7bc23
--- /dev/null
+++ b/include/hw/cxl/cxl_port.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef CXL_PORT_H
+#define CXL_PORT_H
+
+/* CXL r3.2 Table 7-19: Get Physical Port State Port Information Block Format */
+#define CXL_PORT_CONFIG_STATE_DISABLED           0x0
+#define CXL_PORT_CONFIG_STATE_BIND_IN_PROGRESS   0x1
+#define CXL_PORT_CONFIG_STATE_UNBIND_IN_PROGRESS 0x2
+#define CXL_PORT_CONFIG_STATE_DSP                0x3
+#define CXL_PORT_CONFIG_STATE_USP                0x4
+#define CXL_PORT_CONFIG_STATE_FABRIC_PORT        0x5
+#define CXL_PORT_CONFIG_STATE_INVALID_PORT_ID    0xF
+
+#define CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN 0x00
+#define CXL_PORT_CONNECTED_DEV_MODE_RCD                0x01
+#define CXL_PORT_CONNECTED_DEV_MODE_68B_VH             0x02
+#define CXL_PORT_CONNECTED_DEV_MODE_256B               0x03
+#define CXL_PORT_CONNECTED_DEV_MODE_LO_256B            0x04
+#define CXL_PORT_CONNECTED_DEV_MODE_PBR                0x05
+
+#define CXL_PORT_CONNECTED_DEV_TYPE_NONE            0x00
+#define CXL_PORT_CONNECTED_DEV_TYPE_PCIE            0x01
+#define CXL_PORT_CONNECTED_DEV_TYPE_1               0x02
+#define CXL_PORT_CONNECTED_DEV_TYPE_2_OR_HBR_SWITCH 0x03
+#define CXL_PORT_CONNECTED_DEV_TYPE_3_SLD           0x04
+#define CXL_PORT_CONNECTED_DEV_TYPE_3_MLD           0x05
+#define CXL_PORT_CONNECTED_DEV_PBR_COMPONENT        0x06
+
+#define CXL_PORT_SUPPORTS_RCD        BIT(0)
+#define CXL_PORT_SUPPORTS_68B_VH     BIT(1)
+#define CXL_PORT_SUPPORTS_256B       BIT(2)
+#define CXL_PORT_SUPPORTS_LO_256B    BIT(3)
+#define CXL_PORT_SUPPORTS_PBR        BIT(4)
+
+#define CXL_PORT_LTSSM_DETECT        0x00
+#define CXL_PORT_LTSSM_POLLING       0x01
+#define CXL_PORT_LTSSM_CONFIGURATION 0x02
+#define CXL_PORT_LTSSM_RECOVERY      0x03
+#define CXL_PORT_LTSSM_L0            0x04
+#define CXL_PORT_LTSSM_L0S           0x05
+#define CXL_PORT_LTSSM_L1            0x06
+#define CXL_PORT_LTSSM_L2            0x07
+#define CXL_PORT_LTSSM_DISABLED      0x08
+#define CXL_PORT_LTSSM_LOOPBACK      0x09
+#define CXL_PORT_LTSSM_HOT_RESET     0x0A
+
+#define CXL_PORT_LINK_STATE_FLAG_LANE_REVERSED    BIT(0)
+#define CXL_PORT_LINK_STATE_FLAG_PERST_ASSERTED   BIT(1)
+#define CXL_PORT_LINK_STATE_FLAG_PRSNT            BIT(2)
+#define CXL_PORT_LINK_STATE_FLAG_POWER_OFF        BIT(3)
+
+#endif /* CXL_PORT_H */
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 2f449980cdc0..1c8cbe0f682d 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -15,6 +15,7 @@
 #include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_events.h"
 #include "hw/cxl/cxl_mailbox.h"
+#include "hw/cxl/cxl_port.h"
 #include "hw/pci/pci.h"
 #include "hw/pci-bridge/cxl_upstream_port.h"
 #include "qemu/cutils.h"
@@ -565,16 +566,16 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
     } QEMU_PACKED *in;
 
     /*
-     * CXL r3.1 Table 7-19: Get Physical Port State Port Information Block
+     * CXL r3.2 Table 7-19: Get Physical Port State Port Information Block
      * Format
      */
     struct cxl_fmapi_port_state_info_block {
         uint8_t port_id;
         uint8_t config_state;
-        uint8_t connected_device_cxl_version;
+        uint8_t connected_device_mode;
         uint8_t rsv1;
         uint8_t connected_device_type;
-        uint8_t port_cxl_version_bitmask;
+        uint8_t supported_cxl_mode_bitmask;
         uint8_t max_link_width;
         uint8_t negotiated_link_width;
         uint8_t supported_link_speeds_vector;
@@ -623,21 +624,30 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
         if (port_dev) { /* DSP */
             PCIDevice *ds_dev = pci_bridge_get_sec_bus(PCI_BRIDGE(port_dev))
                 ->devices[0];
-            port->config_state = 3;
+            port->config_state = CXL_PORT_CONFIG_STATE_DSP;
             if (ds_dev) {
                 if (object_dynamic_cast(OBJECT(ds_dev), TYPE_CXL_TYPE3)) {
-                    port->connected_device_type = 5; /* Assume MLD for now */
+                    /* Assume MLD for now */
+                    port->connected_device_type =
+                        CXL_PORT_CONNECTED_DEV_TYPE_3_MLD;
                 } else {
-                    port->connected_device_type = 1;
+                    port->connected_device_type =
+                        CXL_PORT_CONNECTED_DEV_TYPE_PCIE;
+                    port->connected_device_mode =
+                        CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN;
+
                 }
             } else {
-                port->connected_device_type = 0;
+                port->connected_device_type = CXL_PORT_CONNECTED_DEV_TYPE_NONE;
+                port->connected_device_mode =
+                    CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN;
             }
             port->supported_ld_count = 3;
         } else if (usp->port == in->ports[i]) { /* USP */
             port_dev = PCI_DEVICE(usp);
-            port->config_state = 4;
-            port->connected_device_type = 0;
+            port->config_state = CXL_PORT_CONFIG_STATE_USP;
+            port->connected_device_type = 0; /* Reserved for USP */
+            port->connected_device_mode = 0; /* Reserved for USP */
         } else {
             return CXL_MBOX_INVALID_INPUT;
         }
@@ -667,8 +677,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
         port->ltssm_state = 0x7;
         port->first_lane_num = 0;
         port->link_state = 0;
-        port->port_cxl_version_bitmask = 0x2;
-        port->connected_device_cxl_version = 0x2;
+        port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH;
     }
 
     pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH qemu v5 2/3] hw/cxl: Get Physical Port State - update for PCIe flit mode
  2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
  2026-02-04 17:32   ` [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines Jonathan Cameron
@ 2026-02-04 17:32   ` Jonathan Cameron
  2026-02-04 17:32   ` [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h) Jonathan Cameron
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-04 17:32 UTC (permalink / raw)
  To: Michael Tsirkin, qemu-devel, Arpit Kumar
  Cc: linuxarm, linux-cxl, Ravi Shankar, Marcel Apfelbaum, Michael Roth

Recent support for 256B flits, was not accounted for in this FMAPI command
that should be retrieving the current status of Physical Switch Ports.

Note x-flit-mode control is via the downstream devices, so for USPs the
property must be checked to establish support, but for DSPs this mode is
always supported (control is with the next port downstream, typically the
end point.  All cases the linksta2 register may be queried to obtain
current status.  Note the PCI spec is a little confusing as it refers to
this bit only being non 0 if Device Readiness Status (DRS) is in particular
states (basically link trained) but Flit mode is a separate feature and DRS
may not be present. It is not yet emulated in QEMU. So assume that we
should reflect what states DRS would be reporting if it were actually
present.

One small thing to note is that the current link width for a port with
nothing connected reports the same as the capability. This is odd but valid
because the value under these circumstances is undefined (PCIe r6.2 table
7-26 Link Status Register - field Current Link Speed.)

Signed-off-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
 hw/cxl/cxl-mailbox-utils.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 1c8cbe0f682d..b6ac987ee021 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -627,9 +627,26 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
             port->config_state = CXL_PORT_CONFIG_STATE_DSP;
             if (ds_dev) {
                 if (object_dynamic_cast(OBJECT(ds_dev), TYPE_CXL_TYPE3)) {
+                    uint16_t lnksta2;
+
+                    if (!port_dev->exp.exp_cap) {
+                        return CXL_MBOX_INTERNAL_ERROR;
+                    }
+
+                    lnksta2 = port_dev->config_read(port_dev,
+                                  port_dev->exp.exp_cap + PCI_EXP_LNKSTA2,
+                                  sizeof(lnksta2));
+
                     /* Assume MLD for now */
                     port->connected_device_type =
                         CXL_PORT_CONNECTED_DEV_TYPE_3_MLD;
+                    if (lnksta2 & PCI_EXP_LNKSTA2_FLIT) {
+                        port->connected_device_mode =
+                            CXL_PORT_CONNECTED_DEV_MODE_256B;
+                    } else {
+                        port->connected_device_mode =
+                            CXL_PORT_CONNECTED_DEV_MODE_68B_VH;
+                    }
                 } else {
                     port->connected_device_type =
                         CXL_PORT_CONNECTED_DEV_TYPE_PCIE;
@@ -642,12 +659,17 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
                 port->connected_device_mode =
                     CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN;
             }
+            /* DSP currently always support modes implemented in QEMU */
+            port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
+                CXL_PORT_SUPPORTS_256B;
             port->supported_ld_count = 3;
         } else if (usp->port == in->ports[i]) { /* USP */
             port_dev = PCI_DEVICE(usp);
             port->config_state = CXL_PORT_CONFIG_STATE_USP;
             port->connected_device_type = 0; /* Reserved for USP */
             port->connected_device_mode = 0; /* Reserved for USP */
+            port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
+                (CXL_USP(usp)->flitmode ? CXL_PORT_SUPPORTS_256B : 0);
         } else {
             return CXL_MBOX_INVALID_INPUT;
         }
@@ -676,8 +698,6 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
         /* TODO: Track down if we can get the rest of the info */
         port->ltssm_state = 0x7;
         port->first_lane_num = 0;
-        port->link_state = 0;
-        port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH;
     }
 
     pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
  2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
  2026-02-04 17:32   ` [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines Jonathan Cameron
  2026-02-04 17:32   ` [PATCH qemu v5 2/3] hw/cxl: Get Physical Port State - update for PCIe flit mode Jonathan Cameron
@ 2026-02-04 17:32   ` Jonathan Cameron
  2026-02-12 15:25     ` Arpit Kumar
  2026-02-12 15:12   ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Arpit Kumar
  2026-02-20 12:58   ` Michael S. Tsirkin
  4 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-04 17:32 UTC (permalink / raw)
  To: Michael Tsirkin, qemu-devel, Arpit Kumar
  Cc: linuxarm, linux-cxl, Ravi Shankar, Marcel Apfelbaum, Michael Roth

From: Arpit Kumar <arpit1.kumar@samsung.com>

Added assert-deassert PERST implementation for physical ports (both USP
and DSP's).

Assert PERST involves bg operation for holding 100ms.
Reset PPB implementation for physical ports.

Signed-off-by: Arpit Kumar <arpit1.kumar@samsung.com>
Co-developed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

---
Changes mostly due to dropping refactor that preceeded this in original
series.
---
 include/hw/cxl/cxl_port.h                   |  20 +++
 include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
 include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
 hw/cxl/cxl-mailbox-utils.c                  | 130 ++++++++++++++++++++
 hw/pci-bridge/cxl_downstream.c              |   9 ++
 hw/pci-bridge/cxl_upstream.c                |   1 +
 6 files changed, 174 insertions(+)

diff --git a/include/hw/cxl/cxl_port.h b/include/hw/cxl/cxl_port.h
index 04db60f7bc23..fb2e22a9f2ae 100644
--- a/include/hw/cxl/cxl_port.h
+++ b/include/hw/cxl/cxl_port.h
@@ -3,6 +3,8 @@
 #ifndef CXL_PORT_H
 #define CXL_PORT_H
 
+#include "qemu/thread.h"
+
 /* CXL r3.2 Table 7-19: Get Physical Port State Port Information Block Format */
 #define CXL_PORT_CONFIG_STATE_DISABLED           0x0
 #define CXL_PORT_CONFIG_STATE_BIND_IN_PROGRESS   0x1
@@ -50,4 +52,22 @@
 #define CXL_PORT_LINK_STATE_FLAG_PRSNT            BIT(2)
 #define CXL_PORT_LINK_STATE_FLAG_POWER_OFF        BIT(3)
 
+#define CXL_MAX_PHY_PORTS 256
+#define ASSERT_WAIT_TIME_MS 100 /* Assert - Deassert PERST */
+
+/* Assert - Deassert PERST */
+typedef struct CXLPhyPortPerst {
+    bool issued_assert_perst;
+    QemuMutex lock; /* protecting assert-deassert reset request */
+    uint64_t asrt_time;
+    QemuThread asrt_thread; /* thread for 100ms delay */
+} CXLPhyPortPerst;
+
+void cxl_init_physical_port_control(CXLPhyPortPerst *perst);
+
+static inline bool cxl_perst_asserted(CXLPhyPortPerst *perst)
+{
+    return perst->issued_assert_perst || perst->asrt_time < ASSERT_WAIT_TIME_MS;
+}
+
 #endif /* CXL_PORT_H */
diff --git a/include/hw/pci-bridge/cxl_downstream_port.h b/include/hw/pci-bridge/cxl_downstream_port.h
new file mode 100644
index 000000000000..1611504c8764
--- /dev/null
+++ b/include/hw/pci-bridge/cxl_downstream_port.h
@@ -0,0 +1,12 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef CXL_DOWNSTREAM_PORT_H
+#define CXL_DOWNSTREAM_PORT_H
+#include "include/hw/cxl/cxl_port.h"
+
+typedef struct CXLDownstreamPort CXLDownstreamPort;
+CXLPhyPortPerst *cxl_dsp_get_perst(CXLDownstreamPort *dsp);
+
+#endif
diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
index e3d6a27acc86..dfe01771c7d7 100644
--- a/include/hw/pci-bridge/cxl_upstream_port.h
+++ b/include/hw/pci-bridge/cxl_upstream_port.h
@@ -4,6 +4,7 @@
 #include "hw/pci/pcie.h"
 #include "hw/pci/pcie_port.h"
 #include "hw/cxl/cxl.h"
+#include "hw/cxl/cxl_port.h"
 
 typedef struct CXLUpstreamPort {
     /*< private >*/
@@ -12,6 +13,7 @@ typedef struct CXLUpstreamPort {
     /*< public >*/
     CXLComponentState cxl_cstate;
     CXLCCI swcci;
+    CXLPhyPortPerst perst;
 
     PCIExpLinkSpeed speed;
     PCIExpLinkWidth width;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index b6ac987ee021..c83b5f90d4d3 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -17,6 +17,7 @@
 #include "hw/cxl/cxl_mailbox.h"
 #include "hw/cxl/cxl_port.h"
 #include "hw/pci/pci.h"
+#include "hw/pci-bridge/cxl_downstream_port.h"
 #include "hw/pci-bridge/cxl_upstream_port.h"
 #include "qemu/cutils.h"
 #include "qemu/host-utils.h"
@@ -119,6 +120,7 @@ enum {
     PHYSICAL_SWITCH = 0x51,
         #define IDENTIFY_SWITCH_DEVICE      0x0
         #define GET_PHYSICAL_PORT_STATE     0x1
+        #define PHYSICAL_PORT_CONTROL       0x2
     TUNNEL = 0x53,
         #define MANAGEMENT_COMMAND     0x0
     FMAPI_DCD_MGMT = 0x56,
@@ -616,6 +618,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
         struct cxl_fmapi_port_state_info_block *port;
         /* First try to match on downstream port */
         PCIDevice *port_dev;
+        CXLPhyPortPerst *perst;
         uint16_t lnkcap, lnkcap2, lnksta;
 
         port = &out->ports[i];
@@ -663,6 +666,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
             port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
                 CXL_PORT_SUPPORTS_256B;
             port->supported_ld_count = 3;
+            perst = cxl_dsp_get_perst(CXL_DSP(port_dev));
         } else if (usp->port == in->ports[i]) { /* USP */
             port_dev = PCI_DEVICE(usp);
             port->config_state = CXL_PORT_CONFIG_STATE_USP;
@@ -670,6 +674,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
             port->connected_device_mode = 0; /* Reserved for USP */
             port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
                 (CXL_USP(usp)->flitmode ? CXL_PORT_SUPPORTS_256B : 0);
+            perst = &CXL_USP(usp)->perst;
         } else {
             return CXL_MBOX_INVALID_INPUT;
         }
@@ -698,6 +703,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
         /* TODO: Track down if we can get the rest of the info */
         port->ltssm_state = 0x7;
         port->first_lane_num = 0;
+        port->link_state = perst ? CXL_PORT_LINK_STATE_FLAG_PERST_ASSERTED : 0;
     }
 
     pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
@@ -706,6 +712,115 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
     return CXL_MBOX_SUCCESS;
 }
 
+static void *bg_assertcb(void *opaque)
+{
+    CXLPhyPortPerst *perst = opaque;
+
+    /* holding reset phase for 100ms */
+    while (perst->asrt_time--) {
+        usleep(1000);
+    }
+    perst->issued_assert_perst = true;
+    return NULL;
+}
+
+static CXLRetCode cxl_deassert_perst(Object *obj, CXLPhyPortPerst *perst)
+{
+    if (!perst->issued_assert_perst) {
+        return CXL_MBOX_INTERNAL_ERROR;
+    }
+
+    QEMU_LOCK_GUARD(&perst->lock);
+    resettable_release_reset(obj, RESET_TYPE_COLD);
+    perst->issued_assert_perst = false;
+    perst->asrt_time = ASSERT_WAIT_TIME_MS;
+
+    return CXL_MBOX_SUCCESS;
+}
+
+static CXLRetCode cxl_assert_perst(Object *obj, CXLPhyPortPerst *perst)
+{
+    if (cxl_perst_asserted(perst)) {
+        return CXL_MBOX_INTERNAL_ERROR;
+    }
+
+    QEMU_LOCK_GUARD(&perst->lock);
+    resettable_assert_reset(obj, RESET_TYPE_COLD);
+    qemu_thread_create(&perst->asrt_thread, "assert_thread", bg_assertcb,
+                       perst, QEMU_THREAD_DETACHED);
+
+    return CXL_MBOX_SUCCESS;
+}
+
+static CXLDownstreamPort *cxl_find_dsp_on_bus(PCIBus *bus, uint8_t pn)
+{
+
+    PCIDevice *port_dev = pcie_find_port_by_pn(bus, pn);
+
+    if (object_dynamic_cast(OBJECT(port_dev), TYPE_CXL_DSP)) {
+        return CXL_DSP(port_dev);
+    }
+
+    return NULL;
+}
+
+/* CXL r3.2 Section 7.6.7.1.3: Get Physical Port Control (Opcode 5102h) */
+static CXLRetCode cmd_physical_port_control(const struct cxl_cmd *cmd,
+                                            uint8_t *payload_in,
+                                            size_t len_in,
+                                            uint8_t *payload_out,
+                                            size_t *len_out,
+                                            CXLCCI *cci)
+{
+   CXLUpstreamPort *pp = CXL_USP(cci->d);
+   CXLPhyPortPerst *perst;
+   PCIDevice *dev;
+
+   struct cxl_fmapi_get_physical_port_control_req_pl {
+        uint8_t ppb_id;
+        uint8_t ports_op;
+    } QEMU_PACKED *in = (void *)payload_in;
+
+    if (len_in < sizeof(*in)) {
+        return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
+    }
+
+    if (PCIE_PORT(pp)->port == in->ppb_id) {
+        dev = PCI_DEVICE(pp);
+        perst = &pp->perst;
+    } else {
+        CXLDownstreamPort *dsp =
+            cxl_find_dsp_on_bus(&PCI_BRIDGE(pp)->sec_bus, in->ppb_id);
+
+        if (!dsp) {
+            return CXL_MBOX_INVALID_INPUT;
+        }
+        dev = PCI_DEVICE(dsp);
+        perst = cxl_dsp_get_perst(dsp);
+    }
+
+    switch (in->ports_op) {
+    case 0:
+        return cxl_assert_perst(OBJECT(&dev->qdev), perst);
+    case 1:
+        return cxl_deassert_perst(OBJECT(&dev->qdev), perst);
+    case 2: {
+        if (!perst) {
+            return CXL_MBOX_INVALID_INPUT;
+        }
+
+        if (perst->issued_assert_perst ||
+            perst->asrt_time < ASSERT_WAIT_TIME_MS) {
+            return CXL_MBOX_INTERNAL_ERROR;
+        }
+        device_cold_reset(&dev->qdev);
+        return CXL_MBOX_SUCCESS;
+    }
+    default:
+        return CXL_MBOX_INVALID_INPUT;
+    }
+}
+
 /* CXL r3.1 Section 8.2.9.1.2: Background Operation Status (Opcode 0002h) */
 static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd,
                                          uint8_t *payload_in,
@@ -4412,6 +4527,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
         cmd_identify_switch_device, 0, 0 },
     [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
         cmd_get_physical_port_state, ~0, 0 },
+    [PHYSICAL_SWITCH][PHYSICAL_PORT_CONTROL] = { "SWITCH_PHYSICAL_PORT_CONTROL",
+        cmd_physical_port_control, 2, 0 },
     [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
                                      cmd_tunnel_management_cmd, ~0, 0 },
 };
@@ -4618,6 +4735,19 @@ static void cxl_rebuild_cel(CXLCCI *cci)
     }
 }
 
+void cxl_init_physical_port_control(CXLPhyPortPerst *perst)
+{
+    qemu_mutex_init(&perst->lock);
+    perst->issued_assert_perst = false;
+    /*
+     * Assert PERST involves physical port to be in
+     * hold reset phase for minimum 100ms. No other
+     * physical port control requests are entertained
+     * until Deassert PERST command.
+     */
+    perst->asrt_time = ASSERT_WAIT_TIME_MS;
+}
+
 void cxl_init_cci(CXLCCI *cci, size_t payload_max)
 {
     cci->payload_max = payload_max;
diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c
index 320818a8f1ce..ec450d1aa09e 100644
--- a/hw/pci-bridge/cxl_downstream.c
+++ b/hw/pci-bridge/cxl_downstream.c
@@ -13,9 +13,11 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/pcie.h"
 #include "hw/pci/pcie_port.h"
+#include "hw/pci-bridge/cxl_downstream_port.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-properties-system.h"
 #include "hw/cxl/cxl.h"
+#include "hw/cxl/cxl_port.h"
 #include "qapi/error.h"
 
 typedef struct CXLDownstreamPort {
@@ -24,6 +26,7 @@ typedef struct CXLDownstreamPort {
 
     /*< public >*/
     CXLComponentState cxl_cstate;
+    CXLPhyPortPerst perst;
 } CXLDownstreamPort;
 
 #define CXL_DOWNSTREAM_PORT_MSI_OFFSET 0x70
@@ -81,6 +84,11 @@ static void cxl_dsp_config_write(PCIDevice *d, uint32_t address,
     cxl_dsp_dvsec_write_config(d, address, val, len);
 }
 
+CXLPhyPortPerst *cxl_dsp_get_perst(CXLDownstreamPort *dsp)
+{
+    return &dsp->perst;
+}
+
 static void cxl_dsp_reset(DeviceState *qdev)
 {
     PCIDevice *d = PCI_DEVICE(qdev);
@@ -92,6 +100,7 @@ static void cxl_dsp_reset(DeviceState *qdev)
     pci_bridge_reset(qdev);
 
     latch_registers(dsp);
+    cxl_init_physical_port_control(&dsp->perst);
 }
 
 static void build_dvsecs(PCIDevice *d, CXLComponentState *cxl)
diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c
index fb8d19539c9f..b6281cbd4cb0 100644
--- a/hw/pci-bridge/cxl_upstream.c
+++ b/hw/pci-bridge/cxl_upstream.c
@@ -103,6 +103,7 @@ static void cxl_usp_reset(DeviceState *qdev)
     pcie_cap_deverr_reset(d);
     pcie_cap_fill_link_ep_usp(d, usp->width, usp->speed, usp->flitmode);
     latch_registers(usp);
+    cxl_init_physical_port_control(&usp->perst);
 }
 
 static void build_dvsecs(CXLUpstreamPort *usp)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support.
  2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
                     ` (2 preceding siblings ...)
  2026-02-04 17:32   ` [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h) Jonathan Cameron
@ 2026-02-12 15:12   ` Arpit Kumar
  2026-02-20 12:58   ` Michael S. Tsirkin
  4 siblings, 0 replies; 10+ messages in thread
From: Arpit Kumar @ 2026-02-12 15:12 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Michael Tsirkin, qemu-devel, linuxarm, linux-cxl, Ravi Shankar,
	Marcel Apfelbaum, Michael Roth, Arpit Kumar, cpgs

[-- Attachment #1: Type: text/plain, Size: 6104 bytes --]

On 04/02/26 05:32PM, Jonathan Cameron wrote:
>Changes since v4:
>https://lore.kernel.org/qemu-devel/20250916080736.1266083-1-arpit1.kumar@samsung.com/
>- Dropped initial refactor. Reason being that it is not static enough
>  for caching at boot to be appropriate.  Kept the spec update part
>  of this.
>- Added a patch to make sure the new flip mode stuff is reported in
>  the Get Physical Port State command.
>- Rebased Arpit's Physical Control Control FMAPI Command given drop
>  of the major refactor from v4 patch 1.
>
>I had taken this into my cxl staging tree thinking it only needed a few
>minor tweaks.  Then whilst testing I realized it didn't work with hotplug
>and that made me consider if Arpit's original approach made sense.
>
>So this is my proposal on how to take this forwards. Note that this is
>not ready for merge (probably) just yet as I'd like Arpit to take a
>look at the changes.  I went through a version that had major refactors
>to push the logic of building the records to the ports themselves, but
>in the end don't think that brings enough benefits for the complexity.
>

Hi Jonathan,
Thanks for the patch series. I have reviewed the changes in detail, and
the approach looks good to me. Thanks for the rework and keeping me in
the loop.

>Based on:
>https://lore.kernel.org/qemu-devel/20260204170936.43959-1-Jonathan.Cameron@huawei.com/T/#t
>(with all it's precursors, though hopefully they will all be in Michael's
>next pull request)
>
>I'll note this is an enormous foot gun as it lets you effectively trigger
>surprise device resets.  However, it's only accessible if you are using
>a configuration with the fabric management parts of the CXL emulation.
>For now that is a switch-cci (MCTP over USB support is near the top
>of my list of things to get ready for upstram.  I tested this with a
>custom driver and if nothing else it exposed some gaps in Linux's
>ability to rescan PCI buses after a perst event (even with drivers
>unbound etc to make it safe).
>
>Original cover letter:
>
>This patch series refactor existing support for Identify Switch Device
>and Get Physical Port State by utilizing physical ports (USP & DSP)
>information stored during enumeration.
>
>Additionally, it introduces new support for Physical Port Control
>of Physical Switch Command Set as per CXL spec r3.2 Section 7.6.7.1.3.
>It primarily constitutes two logic:
>    -Assert-Deassert PERST: Assert PERST involves physical port to be in
>     hold reset phase for minimum 100ms. No other physical port control
>     request are entertained until Deassert PERST command for the given
>     port is issued.
>    -Reset PPB: cold reset of physical port (completing enter->hold->exit
>     phases).
>
>Tested using libcxl-mi interface[1]:
>All active ports and all opcodes per active port is tested. Also, tested
>against possible edge cases manually since the interface currently dosen't
>support run time input.
>
>Typical Qemu topology
>(1 USP + 3 DSP's in a switch with 2 CXLType3 devices connected to the 2 DSP's):
>FM="-object memory-backend-file,id=cxl-mem1,mem-path=$TMP_DIR/t3_cxl1.raw,size=256M \
>    -object memory-backend-file,id=cxl-lsa1,mem-path=$TMP_DIR/t3_lsa1.raw,size=1M \
>    -object memory-backend-file,id=cxl-mem2,mem-path=$TMP_DIR/t3_cxl2.raw,size=512M \
>    -object memory-backend-file,id=cxl-lsa2,mem-path=$TMP_DIR/t3_lsa2.raw,size=512M \
>    -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1,hdm_for_passthrough=true \
>    -device cxl-rp,port=0,bus=cxl.1,id=cxl_rp_port0,chassis=0,slot=2 \
>    -device cxl-upstream,port=2,sn=1234,bus=cxl_rp_port0,id=us0,addr=0.0,multifunction=on, \
>    -device cxl-switch-mailbox-cci,bus=cxl_rp_port0,addr=0.1,target=us0 \
>    -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
>    -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
>    -device cxl-downstream,port=3,bus=us0,id=swport2,chassis=0,slot=6 \
>    -device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 \
>    -device cxl-type3,bus=swport2,memdev=cxl-mem2,id=cxl-pmem2,lsa=cxl-lsa2,sn=4 \
>    -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \
>    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
>    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1 \
>    -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem2 \
>    -device virtio-rng-pci,bus=swport1"
>
>Tested multiple Qemu topologies:
>        -without any devices connected to downstream ports.
>        -with virtio-rng-pci devices connected to downstream ports.
>        -with CXLType3 devices connected to downstream ports.
>        -with different unique values of ports (both upstream and downstream).
>
>Changes from v3 (https://lore.kernel.org/qemu-devel/20250909160316.00000190@huawei.com/T/):
>        -Namespaced the defines with cleaner prefix for Get Physical Port State
>         Port Information Block members.
>        -switch CCI implementation instead of switch FM interface as per
>         Jonathan's review comments, hence moved perst members initializations
>         from: cxl_initialize_usp_mctpcci() -> cxl_initialize_mailbox_swcci().
>
>[1] https://github.com/computexpresslink/libcxlmi/commit/35fe68bd9a31469f832a87694d7b18d2d50be5b8
>
>
>Arpit Kumar (2):
>  hw/cxl: Physical Port Info FMAPI - update to current spec and add
>    defines.
>  hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
>
>Jonathan Cameron (1):
>  hw/cxl: Get Physical Port State - update for PCIe flit mode
>
> include/hw/cxl/cxl_port.h                   |  73 ++++++++
> include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
> include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
> hw/cxl/cxl-mailbox-utils.c                  | 183 ++++++++++++++++++--
> hw/pci-bridge/cxl_downstream.c              |   9 +
> hw/pci-bridge/cxl_upstream.c                |   1 +
> 6 files changed, 268 insertions(+), 12 deletions(-)
> create mode 100644 include/hw/cxl/cxl_port.h
> create mode 100644 include/hw/pci-bridge/cxl_downstream_port.h
>
>-- 
>2.51.0
>

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines.
  2026-02-04 17:32   ` [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines Jonathan Cameron
@ 2026-02-12 15:22     ` Arpit Kumar
  0 siblings, 0 replies; 10+ messages in thread
From: Arpit Kumar @ 2026-02-12 15:22 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Michael Tsirkin, qemu-devel, linuxarm, linux-cxl, Ravi Shankar,
	Marcel Apfelbaum, Michael Roth, Arpit Kumar, cpgs

[-- Attachment #1: Type: text/plain, Size: 7149 bytes --]

On 04/02/26 05:32PM, Jonathan Cameron wrote:
>From: Arpit Kumar <arpit1.kumar@samsung.com>
>
>Add a new cxl/cxl_ports.h header for field definitions related only to port
>commands. Bring field naming up to date with spec as 'version' bitmasks
>have been replaced with bitmasks of the specific features.
>
>Fix a small issue where a reserved value for USP was set to 2 rather
>than 0.
>
>Signed-off-by: Arpit Kumar <arpit1.kumar@samsung.com>
>Co-developed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
>Signed-off-by: Jonathan Cameron <jonathan.cameron@huawei.com>
>
>---
>This is effectively lifted out of Arpit's orginal rework.
>Arpit please confirm you are fine with keeping authorship on this one.
>---

Hi Jonathan,
I'm fine with keeping the authorship on this patch and the split looks
good to me. I only noticed a minor extra line, but nothing functional.

Thanks,
Arpit

> include/hw/cxl/cxl_port.h  | 53 ++++++++++++++++++++++++++++++++++++++
> hw/cxl/cxl-mailbox-utils.c | 31 ++++++++++++++--------
> 2 files changed, 73 insertions(+), 11 deletions(-)
>
>diff --git a/include/hw/cxl/cxl_port.h b/include/hw/cxl/cxl_port.h
>new file mode 100644
>index 000000000000..04db60f7bc23
>--- /dev/null
>+++ b/include/hw/cxl/cxl_port.h
>@@ -0,0 +1,53 @@
>+/* SPDX-License-Identifier: GPL-2.0-or-later */
>+
>+#ifndef CXL_PORT_H
>+#define CXL_PORT_H
>+
>+/* CXL r3.2 Table 7-19: Get Physical Port State Port Information Block Format */
>+#define CXL_PORT_CONFIG_STATE_DISABLED           0x0
>+#define CXL_PORT_CONFIG_STATE_BIND_IN_PROGRESS   0x1
>+#define CXL_PORT_CONFIG_STATE_UNBIND_IN_PROGRESS 0x2
>+#define CXL_PORT_CONFIG_STATE_DSP                0x3
>+#define CXL_PORT_CONFIG_STATE_USP                0x4
>+#define CXL_PORT_CONFIG_STATE_FABRIC_PORT        0x5
>+#define CXL_PORT_CONFIG_STATE_INVALID_PORT_ID    0xF
>+
>+#define CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN 0x00
>+#define CXL_PORT_CONNECTED_DEV_MODE_RCD                0x01
>+#define CXL_PORT_CONNECTED_DEV_MODE_68B_VH             0x02
>+#define CXL_PORT_CONNECTED_DEV_MODE_256B               0x03
>+#define CXL_PORT_CONNECTED_DEV_MODE_LO_256B            0x04
>+#define CXL_PORT_CONNECTED_DEV_MODE_PBR                0x05
>+
>+#define CXL_PORT_CONNECTED_DEV_TYPE_NONE            0x00
>+#define CXL_PORT_CONNECTED_DEV_TYPE_PCIE            0x01
>+#define CXL_PORT_CONNECTED_DEV_TYPE_1               0x02
>+#define CXL_PORT_CONNECTED_DEV_TYPE_2_OR_HBR_SWITCH 0x03
>+#define CXL_PORT_CONNECTED_DEV_TYPE_3_SLD           0x04
>+#define CXL_PORT_CONNECTED_DEV_TYPE_3_MLD           0x05
>+#define CXL_PORT_CONNECTED_DEV_PBR_COMPONENT        0x06
>+
>+#define CXL_PORT_SUPPORTS_RCD        BIT(0)
>+#define CXL_PORT_SUPPORTS_68B_VH     BIT(1)
>+#define CXL_PORT_SUPPORTS_256B       BIT(2)
>+#define CXL_PORT_SUPPORTS_LO_256B    BIT(3)
>+#define CXL_PORT_SUPPORTS_PBR        BIT(4)
>+
>+#define CXL_PORT_LTSSM_DETECT        0x00
>+#define CXL_PORT_LTSSM_POLLING       0x01
>+#define CXL_PORT_LTSSM_CONFIGURATION 0x02
>+#define CXL_PORT_LTSSM_RECOVERY      0x03
>+#define CXL_PORT_LTSSM_L0            0x04
>+#define CXL_PORT_LTSSM_L0S           0x05
>+#define CXL_PORT_LTSSM_L1            0x06
>+#define CXL_PORT_LTSSM_L2            0x07
>+#define CXL_PORT_LTSSM_DISABLED      0x08
>+#define CXL_PORT_LTSSM_LOOPBACK      0x09
>+#define CXL_PORT_LTSSM_HOT_RESET     0x0A
>+
>+#define CXL_PORT_LINK_STATE_FLAG_LANE_REVERSED    BIT(0)
>+#define CXL_PORT_LINK_STATE_FLAG_PERST_ASSERTED   BIT(1)
>+#define CXL_PORT_LINK_STATE_FLAG_PRSNT            BIT(2)
>+#define CXL_PORT_LINK_STATE_FLAG_POWER_OFF        BIT(3)
>+
>+#endif /* CXL_PORT_H */
>diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
>index 2f449980cdc0..1c8cbe0f682d 100644
>--- a/hw/cxl/cxl-mailbox-utils.c
>+++ b/hw/cxl/cxl-mailbox-utils.c
>@@ -15,6 +15,7 @@
> #include "hw/cxl/cxl.h"
> #include "hw/cxl/cxl_events.h"
> #include "hw/cxl/cxl_mailbox.h"
>+#include "hw/cxl/cxl_port.h"
> #include "hw/pci/pci.h"
> #include "hw/pci-bridge/cxl_upstream_port.h"
> #include "qemu/cutils.h"
>@@ -565,16 +566,16 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>     } QEMU_PACKED *in;
>
>     /*
>-     * CXL r3.1 Table 7-19: Get Physical Port State Port Information Block
>+     * CXL r3.2 Table 7-19: Get Physical Port State Port Information Block
>      * Format
>      */
>     struct cxl_fmapi_port_state_info_block {
>         uint8_t port_id;
>         uint8_t config_state;
>-        uint8_t connected_device_cxl_version;
>+        uint8_t connected_device_mode;
>         uint8_t rsv1;
>         uint8_t connected_device_type;
>-        uint8_t port_cxl_version_bitmask;
>+        uint8_t supported_cxl_mode_bitmask;
>         uint8_t max_link_width;
>         uint8_t negotiated_link_width;
>         uint8_t supported_link_speeds_vector;
>@@ -623,21 +624,30 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>         if (port_dev) { /* DSP */
>             PCIDevice *ds_dev = pci_bridge_get_sec_bus(PCI_BRIDGE(port_dev))
>                 ->devices[0];
>-            port->config_state = 3;
>+            port->config_state = CXL_PORT_CONFIG_STATE_DSP;
>             if (ds_dev) {
>                 if (object_dynamic_cast(OBJECT(ds_dev), TYPE_CXL_TYPE3)) {
>-                    port->connected_device_type = 5; /* Assume MLD for now */
>+                    /* Assume MLD for now */
>+                    port->connected_device_type =
>+                        CXL_PORT_CONNECTED_DEV_TYPE_3_MLD;
>                 } else {
>-                    port->connected_device_type = 1;
>+                    port->connected_device_type =
>+                        CXL_PORT_CONNECTED_DEV_TYPE_PCIE;
>+                    port->connected_device_mode =
>+                        CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN;
>+
I believe this extra line can be removed here.
>                 }
>             } else {
>-                port->connected_device_type = 0;
>+                port->connected_device_type = CXL_PORT_CONNECTED_DEV_TYPE_NONE;
>+                port->connected_device_mode =
>+                    CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN;
>             }
>             port->supported_ld_count = 3;
>         } else if (usp->port == in->ports[i]) { /* USP */
>             port_dev = PCI_DEVICE(usp);
>-            port->config_state = 4;
>-            port->connected_device_type = 0;
>+            port->config_state = CXL_PORT_CONFIG_STATE_USP;
>+            port->connected_device_type = 0; /* Reserved for USP */
>+            port->connected_device_mode = 0; /* Reserved for USP */
>         } else {
>             return CXL_MBOX_INVALID_INPUT;
>         }
>@@ -667,8 +677,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>         port->ltssm_state = 0x7;
>         port->first_lane_num = 0;
>         port->link_state = 0;
>-        port->port_cxl_version_bitmask = 0x2;
>-        port->connected_device_cxl_version = 0x2;
>+        port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH;
>     }
>
>     pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
>-- 
>2.51.0
>

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
  2026-02-04 17:32   ` [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h) Jonathan Cameron
@ 2026-02-12 15:25     ` Arpit Kumar
  0 siblings, 0 replies; 10+ messages in thread
From: Arpit Kumar @ 2026-02-12 15:25 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Michael Tsirkin, qemu-devel, linuxarm, linux-cxl, Ravi Shankar,
	Marcel Apfelbaum, Michael Roth, Arpit Kumar, cpgs

[-- Attachment #1: Type: text/plain, Size: 12302 bytes --]

On 04/02/26 05:32PM, Jonathan Cameron wrote:
>From: Arpit Kumar <arpit1.kumar@samsung.com>
>
>Added assert-deassert PERST implementation for physical ports (both USP
>and DSP's).
>
>Assert PERST involves bg operation for holding 100ms.
>Reset PPB implementation for physical ports.
>
>Signed-off-by: Arpit Kumar <arpit1.kumar@samsung.com>
>Co-developed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
>---
>Changes mostly due to dropping refactor that preceeded this in original
>series.

Looks good to me!
>---
> include/hw/cxl/cxl_port.h                   |  20 +++
> include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
> include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
> hw/cxl/cxl-mailbox-utils.c                  | 130 ++++++++++++++++++++
> hw/pci-bridge/cxl_downstream.c              |   9 ++
> hw/pci-bridge/cxl_upstream.c                |   1 +
> 6 files changed, 174 insertions(+)
>
>diff --git a/include/hw/cxl/cxl_port.h b/include/hw/cxl/cxl_port.h
>index 04db60f7bc23..fb2e22a9f2ae 100644
>--- a/include/hw/cxl/cxl_port.h
>+++ b/include/hw/cxl/cxl_port.h
>@@ -3,6 +3,8 @@
> #ifndef CXL_PORT_H
> #define CXL_PORT_H
>
>+#include "qemu/thread.h"
>+
> /* CXL r3.2 Table 7-19: Get Physical Port State Port Information Block Format */
> #define CXL_PORT_CONFIG_STATE_DISABLED           0x0
> #define CXL_PORT_CONFIG_STATE_BIND_IN_PROGRESS   0x1
>@@ -50,4 +52,22 @@
> #define CXL_PORT_LINK_STATE_FLAG_PRSNT            BIT(2)
> #define CXL_PORT_LINK_STATE_FLAG_POWER_OFF        BIT(3)
>
>+#define CXL_MAX_PHY_PORTS 256
>+#define ASSERT_WAIT_TIME_MS 100 /* Assert - Deassert PERST */
>+
>+/* Assert - Deassert PERST */
>+typedef struct CXLPhyPortPerst {
>+    bool issued_assert_perst;
>+    QemuMutex lock; /* protecting assert-deassert reset request */
>+    uint64_t asrt_time;
>+    QemuThread asrt_thread; /* thread for 100ms delay */
>+} CXLPhyPortPerst;
>+
>+void cxl_init_physical_port_control(CXLPhyPortPerst *perst);
>+
>+static inline bool cxl_perst_asserted(CXLPhyPortPerst *perst)
>+{
>+    return perst->issued_assert_perst || perst->asrt_time < ASSERT_WAIT_TIME_MS;
>+}
>+
> #endif /* CXL_PORT_H */
>diff --git a/include/hw/pci-bridge/cxl_downstream_port.h b/include/hw/pci-bridge/cxl_downstream_port.h
>new file mode 100644
>index 000000000000..1611504c8764
>--- /dev/null
>+++ b/include/hw/pci-bridge/cxl_downstream_port.h
>@@ -0,0 +1,12 @@
>+/*
>+ * SPDX-License-Identifier: GPL-2.0-or-later
>+ */
>+
>+#ifndef CXL_DOWNSTREAM_PORT_H
>+#define CXL_DOWNSTREAM_PORT_H
>+#include "include/hw/cxl/cxl_port.h"
>+
>+typedef struct CXLDownstreamPort CXLDownstreamPort;
>+CXLPhyPortPerst *cxl_dsp_get_perst(CXLDownstreamPort *dsp);
>+
>+#endif
>diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
>index e3d6a27acc86..dfe01771c7d7 100644
>--- a/include/hw/pci-bridge/cxl_upstream_port.h
>+++ b/include/hw/pci-bridge/cxl_upstream_port.h
>@@ -4,6 +4,7 @@
> #include "hw/pci/pcie.h"
> #include "hw/pci/pcie_port.h"
> #include "hw/cxl/cxl.h"
>+#include "hw/cxl/cxl_port.h"
>
> typedef struct CXLUpstreamPort {
>     /*< private >*/
>@@ -12,6 +13,7 @@ typedef struct CXLUpstreamPort {
>     /*< public >*/
>     CXLComponentState cxl_cstate;
>     CXLCCI swcci;
>+    CXLPhyPortPerst perst;
>
>     PCIExpLinkSpeed speed;
>     PCIExpLinkWidth width;
>diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
>index b6ac987ee021..c83b5f90d4d3 100644
>--- a/hw/cxl/cxl-mailbox-utils.c
>+++ b/hw/cxl/cxl-mailbox-utils.c
>@@ -17,6 +17,7 @@
> #include "hw/cxl/cxl_mailbox.h"
> #include "hw/cxl/cxl_port.h"
> #include "hw/pci/pci.h"
>+#include "hw/pci-bridge/cxl_downstream_port.h"
> #include "hw/pci-bridge/cxl_upstream_port.h"
> #include "qemu/cutils.h"
> #include "qemu/host-utils.h"
>@@ -119,6 +120,7 @@ enum {
>     PHYSICAL_SWITCH = 0x51,
>         #define IDENTIFY_SWITCH_DEVICE      0x0
>         #define GET_PHYSICAL_PORT_STATE     0x1
>+        #define PHYSICAL_PORT_CONTROL       0x2
>     TUNNEL = 0x53,
>         #define MANAGEMENT_COMMAND     0x0
>     FMAPI_DCD_MGMT = 0x56,
>@@ -616,6 +618,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>         struct cxl_fmapi_port_state_info_block *port;
>         /* First try to match on downstream port */
>         PCIDevice *port_dev;
>+        CXLPhyPortPerst *perst;
>         uint16_t lnkcap, lnkcap2, lnksta;
>
>         port = &out->ports[i];
>@@ -663,6 +666,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>             port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
>                 CXL_PORT_SUPPORTS_256B;
>             port->supported_ld_count = 3;
>+            perst = cxl_dsp_get_perst(CXL_DSP(port_dev));
>         } else if (usp->port == in->ports[i]) { /* USP */
>             port_dev = PCI_DEVICE(usp);
>             port->config_state = CXL_PORT_CONFIG_STATE_USP;
>@@ -670,6 +674,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>             port->connected_device_mode = 0; /* Reserved for USP */
>             port->supported_cxl_mode_bitmask = CXL_PORT_SUPPORTS_68B_VH |
>                 (CXL_USP(usp)->flitmode ? CXL_PORT_SUPPORTS_256B : 0);
>+            perst = &CXL_USP(usp)->perst;
>         } else {
>             return CXL_MBOX_INVALID_INPUT;
>         }
>@@ -698,6 +703,7 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>         /* TODO: Track down if we can get the rest of the info */
>         port->ltssm_state = 0x7;
>         port->first_lane_num = 0;
>+        port->link_state = perst ? CXL_PORT_LINK_STATE_FLAG_PERST_ASSERTED : 0;
>     }
>
>     pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
>@@ -706,6 +712,115 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>     return CXL_MBOX_SUCCESS;
> }
>
>+static void *bg_assertcb(void *opaque)
>+{
>+    CXLPhyPortPerst *perst = opaque;
>+
>+    /* holding reset phase for 100ms */
>+    while (perst->asrt_time--) {
>+        usleep(1000);
>+    }
>+    perst->issued_assert_perst = true;
>+    return NULL;
>+}
>+
>+static CXLRetCode cxl_deassert_perst(Object *obj, CXLPhyPortPerst *perst)
>+{
>+    if (!perst->issued_assert_perst) {
>+        return CXL_MBOX_INTERNAL_ERROR;
>+    }
>+
>+    QEMU_LOCK_GUARD(&perst->lock);
>+    resettable_release_reset(obj, RESET_TYPE_COLD);
>+    perst->issued_assert_perst = false;
>+    perst->asrt_time = ASSERT_WAIT_TIME_MS;
>+
>+    return CXL_MBOX_SUCCESS;
>+}
>+
>+static CXLRetCode cxl_assert_perst(Object *obj, CXLPhyPortPerst *perst)
>+{
>+    if (cxl_perst_asserted(perst)) {
>+        return CXL_MBOX_INTERNAL_ERROR;
>+    }
>+
>+    QEMU_LOCK_GUARD(&perst->lock);
>+    resettable_assert_reset(obj, RESET_TYPE_COLD);
>+    qemu_thread_create(&perst->asrt_thread, "assert_thread", bg_assertcb,
>+                       perst, QEMU_THREAD_DETACHED);
>+
>+    return CXL_MBOX_SUCCESS;
>+}
>+
>+static CXLDownstreamPort *cxl_find_dsp_on_bus(PCIBus *bus, uint8_t pn)
>+{
>+
>+    PCIDevice *port_dev = pcie_find_port_by_pn(bus, pn);
>+
>+    if (object_dynamic_cast(OBJECT(port_dev), TYPE_CXL_DSP)) {
>+        return CXL_DSP(port_dev);
>+    }
>+
>+    return NULL;
>+}
>+
>+/* CXL r3.2 Section 7.6.7.1.3: Get Physical Port Control (Opcode 5102h) */
>+static CXLRetCode cmd_physical_port_control(const struct cxl_cmd *cmd,
>+                                            uint8_t *payload_in,
>+                                            size_t len_in,
>+                                            uint8_t *payload_out,
>+                                            size_t *len_out,
>+                                            CXLCCI *cci)
>+{
>+   CXLUpstreamPort *pp = CXL_USP(cci->d);
>+   CXLPhyPortPerst *perst;
>+   PCIDevice *dev;
>+
>+   struct cxl_fmapi_get_physical_port_control_req_pl {
>+        uint8_t ppb_id;
>+        uint8_t ports_op;
>+    } QEMU_PACKED *in = (void *)payload_in;
>+
>+    if (len_in < sizeof(*in)) {
>+        return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
>+    }
>+
>+    if (PCIE_PORT(pp)->port == in->ppb_id) {
>+        dev = PCI_DEVICE(pp);
>+        perst = &pp->perst;
>+    } else {
>+        CXLDownstreamPort *dsp =
>+            cxl_find_dsp_on_bus(&PCI_BRIDGE(pp)->sec_bus, in->ppb_id);
>+
>+        if (!dsp) {
>+            return CXL_MBOX_INVALID_INPUT;
>+        }
>+        dev = PCI_DEVICE(dsp);
>+        perst = cxl_dsp_get_perst(dsp);
>+    }
>+
>+    switch (in->ports_op) {
>+    case 0:
>+        return cxl_assert_perst(OBJECT(&dev->qdev), perst);
>+    case 1:
>+        return cxl_deassert_perst(OBJECT(&dev->qdev), perst);
>+    case 2: {
>+        if (!perst) {
>+            return CXL_MBOX_INVALID_INPUT;
>+        }
>+
>+        if (perst->issued_assert_perst ||
>+            perst->asrt_time < ASSERT_WAIT_TIME_MS) {
>+            return CXL_MBOX_INTERNAL_ERROR;
>+        }
>+        device_cold_reset(&dev->qdev);
>+        return CXL_MBOX_SUCCESS;
>+    }
>+    default:
>+        return CXL_MBOX_INVALID_INPUT;
>+    }
>+}
>+
> /* CXL r3.1 Section 8.2.9.1.2: Background Operation Status (Opcode 0002h) */
> static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd,
>                                          uint8_t *payload_in,
>@@ -4412,6 +4527,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
>         cmd_identify_switch_device, 0, 0 },
>     [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
>         cmd_get_physical_port_state, ~0, 0 },
>+    [PHYSICAL_SWITCH][PHYSICAL_PORT_CONTROL] = { "SWITCH_PHYSICAL_PORT_CONTROL",
>+        cmd_physical_port_control, 2, 0 },
>     [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
>                                      cmd_tunnel_management_cmd, ~0, 0 },
> };
>@@ -4618,6 +4735,19 @@ static void cxl_rebuild_cel(CXLCCI *cci)
>     }
> }
>
>+void cxl_init_physical_port_control(CXLPhyPortPerst *perst)
>+{
>+    qemu_mutex_init(&perst->lock);
>+    perst->issued_assert_perst = false;
>+    /*
>+     * Assert PERST involves physical port to be in
>+     * hold reset phase for minimum 100ms. No other
>+     * physical port control requests are entertained
>+     * until Deassert PERST command.
>+     */
>+    perst->asrt_time = ASSERT_WAIT_TIME_MS;
>+}
>+
> void cxl_init_cci(CXLCCI *cci, size_t payload_max)
> {
>     cci->payload_max = payload_max;
>diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c
>index 320818a8f1ce..ec450d1aa09e 100644
>--- a/hw/pci-bridge/cxl_downstream.c
>+++ b/hw/pci-bridge/cxl_downstream.c
>@@ -13,9 +13,11 @@
> #include "hw/pci/msi.h"
> #include "hw/pci/pcie.h"
> #include "hw/pci/pcie_port.h"
>+#include "hw/pci-bridge/cxl_downstream_port.h"
> #include "hw/core/qdev-properties.h"
> #include "hw/core/qdev-properties-system.h"
> #include "hw/cxl/cxl.h"
>+#include "hw/cxl/cxl_port.h"
> #include "qapi/error.h"
>
> typedef struct CXLDownstreamPort {
>@@ -24,6 +26,7 @@ typedef struct CXLDownstreamPort {
>
>     /*< public >*/
>     CXLComponentState cxl_cstate;
>+    CXLPhyPortPerst perst;
> } CXLDownstreamPort;
>
> #define CXL_DOWNSTREAM_PORT_MSI_OFFSET 0x70
>@@ -81,6 +84,11 @@ static void cxl_dsp_config_write(PCIDevice *d, uint32_t address,
>     cxl_dsp_dvsec_write_config(d, address, val, len);
> }
>
>+CXLPhyPortPerst *cxl_dsp_get_perst(CXLDownstreamPort *dsp)
>+{
>+    return &dsp->perst;
>+}
>+
> static void cxl_dsp_reset(DeviceState *qdev)
> {
>     PCIDevice *d = PCI_DEVICE(qdev);
>@@ -92,6 +100,7 @@ static void cxl_dsp_reset(DeviceState *qdev)
>     pci_bridge_reset(qdev);
>
>     latch_registers(dsp);
>+    cxl_init_physical_port_control(&dsp->perst);
> }
>
> static void build_dvsecs(PCIDevice *d, CXLComponentState *cxl)
>diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c
>index fb8d19539c9f..b6281cbd4cb0 100644
>--- a/hw/pci-bridge/cxl_upstream.c
>+++ b/hw/pci-bridge/cxl_upstream.c
>@@ -103,6 +103,7 @@ static void cxl_usp_reset(DeviceState *qdev)
>     pcie_cap_deverr_reset(d);
>     pcie_cap_fill_link_ep_usp(d, usp->width, usp->speed, usp->flitmode);
>     latch_registers(usp);
>+    cxl_init_physical_port_control(&usp->perst);
> }
>
> static void build_dvsecs(CXLUpstreamPort *usp)
>-- 
>2.51.0
>

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support.
  2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
                     ` (3 preceding siblings ...)
  2026-02-12 15:12   ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Arpit Kumar
@ 2026-02-20 12:58   ` Michael S. Tsirkin
  2026-02-23 11:01     ` Jonathan Cameron
  4 siblings, 1 reply; 10+ messages in thread
From: Michael S. Tsirkin @ 2026-02-20 12:58 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: qemu-devel, Arpit Kumar, linuxarm, linux-cxl, Ravi Shankar,
	Marcel Apfelbaum, Michael Roth

On Wed, Feb 04, 2026 at 05:32:20PM +0000, Jonathan Cameron wrote:
> Changes since v4:
> https://lore.kernel.org/qemu-devel/20250916080736.1266083-1-arpit1.kumar@samsung.com/
> - Dropped initial refactor. Reason being that it is not static enough
>   for caching at boot to be appropriate.  Kept the spec update part
>   of this.
> - Added a patch to make sure the new flip mode stuff is reported in
>   the Get Physical Port State command.
> - Rebased Arpit's Physical Control Control FMAPI Command given drop
>   of the major refactor from v4 patch 1.
> 
> I had taken this into my cxl staging tree thinking it only needed a few
> minor tweaks.  Then whilst testing I realized it didn't work with hotplug
> and that made me consider if Arpit's original approach made sense.
> 
> So this is my proposal on how to take this forwards. Note that this is
> not ready for merge (probably) just yet as I'd like Arpit to take a
> look at the changes.

I'd appreciate it if you add rfc in the subject in such cases.
Thanks!

>  I went through a version that had major refactors
> to push the logic of building the records to the ports themselves, but
> in the end don't think that brings enough benefits for the complexity.
> 
> Based on:
> https://lore.kernel.org/qemu-devel/20260204170936.43959-1-Jonathan.Cameron@huawei.com/T/#t
> (with all it's precursors, though hopefully they will all be in Michael's
> next pull request)
> 
> I'll note this is an enormous foot gun as it lets you effectively trigger
> surprise device resets.  However, it's only accessible if you are using
> a configuration with the fabric management parts of the CXL emulation.
> For now that is a switch-cci (MCTP over USB support is near the top
> of my list of things to get ready for upstram.  I tested this with a
> custom driver and if nothing else it exposed some gaps in Linux's
> ability to rescan PCI buses after a perst event (even with drivers
> unbound etc to make it safe).
> 
> Original cover letter:
> 
> This patch series refactor existing support for Identify Switch Device
> and Get Physical Port State by utilizing physical ports (USP & DSP)
> information stored during enumeration.
> 
> Additionally, it introduces new support for Physical Port Control
> of Physical Switch Command Set as per CXL spec r3.2 Section 7.6.7.1.3.
> It primarily constitutes two logic:
>     -Assert-Deassert PERST: Assert PERST involves physical port to be in
>      hold reset phase for minimum 100ms. No other physical port control
>      request are entertained until Deassert PERST command for the given
>      port is issued.
>     -Reset PPB: cold reset of physical port (completing enter->hold->exit
>      phases).
> 
> Tested using libcxl-mi interface[1]:
> All active ports and all opcodes per active port is tested. Also, tested
> against possible edge cases manually since the interface currently dosen't
> support run time input.
> 
> Typical Qemu topology
> (1 USP + 3 DSP's in a switch with 2 CXLType3 devices connected to the 2 DSP's):
> FM="-object memory-backend-file,id=cxl-mem1,mem-path=$TMP_DIR/t3_cxl1.raw,size=256M \
>     -object memory-backend-file,id=cxl-lsa1,mem-path=$TMP_DIR/t3_lsa1.raw,size=1M \
>     -object memory-backend-file,id=cxl-mem2,mem-path=$TMP_DIR/t3_cxl2.raw,size=512M \
>     -object memory-backend-file,id=cxl-lsa2,mem-path=$TMP_DIR/t3_lsa2.raw,size=512M \
>     -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1,hdm_for_passthrough=true \
>     -device cxl-rp,port=0,bus=cxl.1,id=cxl_rp_port0,chassis=0,slot=2 \
>     -device cxl-upstream,port=2,sn=1234,bus=cxl_rp_port0,id=us0,addr=0.0,multifunction=on, \
>     -device cxl-switch-mailbox-cci,bus=cxl_rp_port0,addr=0.1,target=us0 \
>     -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
>     -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
>     -device cxl-downstream,port=3,bus=us0,id=swport2,chassis=0,slot=6 \
>     -device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 \
>     -device cxl-type3,bus=swport2,memdev=cxl-mem2,id=cxl-pmem2,lsa=cxl-lsa2,sn=4 \
>     -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \
>     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
>     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1 \
>     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem2 \
>     -device virtio-rng-pci,bus=swport1"
> 
> Tested multiple Qemu topologies:
>         -without any devices connected to downstream ports.
>         -with virtio-rng-pci devices connected to downstream ports.
>         -with CXLType3 devices connected to downstream ports.
>         -with different unique values of ports (both upstream and downstream).
> 
> Changes from v3 (https://lore.kernel.org/qemu-devel/20250909160316.00000190@huawei.com/T/):
>         -Namespaced the defines with cleaner prefix for Get Physical Port State 
>          Port Information Block members.
>         -switch CCI implementation instead of switch FM interface as per
>          Jonathan's review comments, hence moved perst members initializations
>          from: cxl_initialize_usp_mctpcci() -> cxl_initialize_mailbox_swcci().
> 
> [1] https://github.com/computexpresslink/libcxlmi/commit/35fe68bd9a31469f832a87694d7b18d2d50be5b8
> 
> 
> Arpit Kumar (2):
>   hw/cxl: Physical Port Info FMAPI - update to current spec and add
>     defines.
>   hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
> 
> Jonathan Cameron (1):
>   hw/cxl: Get Physical Port State - update for PCIe flit mode
> 
>  include/hw/cxl/cxl_port.h                   |  73 ++++++++
>  include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
>  include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
>  hw/cxl/cxl-mailbox-utils.c                  | 183 ++++++++++++++++++--
>  hw/pci-bridge/cxl_downstream.c              |   9 +
>  hw/pci-bridge/cxl_upstream.c                |   1 +
>  6 files changed, 268 insertions(+), 12 deletions(-)
>  create mode 100644 include/hw/cxl/cxl_port.h
>  create mode 100644 include/hw/pci-bridge/cxl_downstream_port.h
> 
> -- 
> 2.51.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support.
  2026-02-20 12:58   ` Michael S. Tsirkin
@ 2026-02-23 11:01     ` Jonathan Cameron
  2026-02-23 11:28       ` Jonathan Cameron
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-23 11:01 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, Arpit Kumar, linuxarm, linux-cxl, Ravi Shankar,
	Marcel Apfelbaum, Michael Roth

On Fri, 20 Feb 2026 07:58:49 -0500
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Feb 04, 2026 at 05:32:20PM +0000, Jonathan Cameron wrote:
> > Changes since v4:
> > https://lore.kernel.org/qemu-devel/20250916080736.1266083-1-arpit1.kumar@samsung.com/
> > - Dropped initial refactor. Reason being that it is not static enough
> >   for caching at boot to be appropriate.  Kept the spec update part
> >   of this.
> > - Added a patch to make sure the new flip mode stuff is reported in
> >   the Get Physical Port State command.
> > - Rebased Arpit's Physical Control Control FMAPI Command given drop
> >   of the major refactor from v4 patch 1.
> > 
> > I had taken this into my cxl staging tree thinking it only needed a few
> > minor tweaks.  Then whilst testing I realized it didn't work with hotplug
> > and that made me consider if Arpit's original approach made sense.
> > 
> > So this is my proposal on how to take this forwards. Note that this is
> > not ready for merge (probably) just yet as I'd like Arpit to take a
> > look at the changes.  
> 
> I'd appreciate it if you add rfc in the subject in such cases.
> Thanks!

Will do.

Arpit is happy with this, so now I think main thing it needs is review of the
PCI interactions and the resets.  They seem fine to me but I'm not that
familiar with that stuff so am relying on PCI / reset experts.

That part is all in patch 3.  If you are happy with that part, then I'm
very much in favor of merging this.

Jonathan

> 
> >  I went through a version that had major refactors
> > to push the logic of building the records to the ports themselves, but
> > in the end don't think that brings enough benefits for the complexity.
> > 
> > Based on:
> > https://lore.kernel.org/qemu-devel/20260204170936.43959-1-Jonathan.Cameron@huawei.com/T/#t
> > (with all it's precursors, though hopefully they will all be in Michael's
> > next pull request)
> > 
> > I'll note this is an enormous foot gun as it lets you effectively trigger
> > surprise device resets.  However, it's only accessible if you are using
> > a configuration with the fabric management parts of the CXL emulation.
> > For now that is a switch-cci (MCTP over USB support is near the top
> > of my list of things to get ready for upstram.  I tested this with a
> > custom driver and if nothing else it exposed some gaps in Linux's
> > ability to rescan PCI buses after a perst event (even with drivers
> > unbound etc to make it safe).
> > 
> > Original cover letter:
> > 
> > This patch series refactor existing support for Identify Switch Device
> > and Get Physical Port State by utilizing physical ports (USP & DSP)
> > information stored during enumeration.
> > 
> > Additionally, it introduces new support for Physical Port Control
> > of Physical Switch Command Set as per CXL spec r3.2 Section 7.6.7.1.3.
> > It primarily constitutes two logic:
> >     -Assert-Deassert PERST: Assert PERST involves physical port to be in
> >      hold reset phase for minimum 100ms. No other physical port control
> >      request are entertained until Deassert PERST command for the given
> >      port is issued.
> >     -Reset PPB: cold reset of physical port (completing enter->hold->exit
> >      phases).
> > 
> > Tested using libcxl-mi interface[1]:
> > All active ports and all opcodes per active port is tested. Also, tested
> > against possible edge cases manually since the interface currently dosen't
> > support run time input.
> > 
> > Typical Qemu topology
> > (1 USP + 3 DSP's in a switch with 2 CXLType3 devices connected to the 2 DSP's):
> > FM="-object memory-backend-file,id=cxl-mem1,mem-path=$TMP_DIR/t3_cxl1.raw,size=256M \
> >     -object memory-backend-file,id=cxl-lsa1,mem-path=$TMP_DIR/t3_lsa1.raw,size=1M \
> >     -object memory-backend-file,id=cxl-mem2,mem-path=$TMP_DIR/t3_cxl2.raw,size=512M \
> >     -object memory-backend-file,id=cxl-lsa2,mem-path=$TMP_DIR/t3_lsa2.raw,size=512M \
> >     -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1,hdm_for_passthrough=true \
> >     -device cxl-rp,port=0,bus=cxl.1,id=cxl_rp_port0,chassis=0,slot=2 \
> >     -device cxl-upstream,port=2,sn=1234,bus=cxl_rp_port0,id=us0,addr=0.0,multifunction=on, \
> >     -device cxl-switch-mailbox-cci,bus=cxl_rp_port0,addr=0.1,target=us0 \
> >     -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
> >     -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
> >     -device cxl-downstream,port=3,bus=us0,id=swport2,chassis=0,slot=6 \
> >     -device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 \
> >     -device cxl-type3,bus=swport2,memdev=cxl-mem2,id=cxl-pmem2,lsa=cxl-lsa2,sn=4 \
> >     -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \
> >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
> >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1 \
> >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem2 \
> >     -device virtio-rng-pci,bus=swport1"
> > 
> > Tested multiple Qemu topologies:
> >         -without any devices connected to downstream ports.
> >         -with virtio-rng-pci devices connected to downstream ports.
> >         -with CXLType3 devices connected to downstream ports.
> >         -with different unique values of ports (both upstream and downstream).
> > 
> > Changes from v3 (https://lore.kernel.org/qemu-devel/20250909160316.00000190@huawei.com/T/):
> >         -Namespaced the defines with cleaner prefix for Get Physical Port State 
> >          Port Information Block members.
> >         -switch CCI implementation instead of switch FM interface as per
> >          Jonathan's review comments, hence moved perst members initializations
> >          from: cxl_initialize_usp_mctpcci() -> cxl_initialize_mailbox_swcci().
> > 
> > [1] https://github.com/computexpresslink/libcxlmi/commit/35fe68bd9a31469f832a87694d7b18d2d50be5b8
> > 
> > 
> > Arpit Kumar (2):
> >   hw/cxl: Physical Port Info FMAPI - update to current spec and add
> >     defines.
> >   hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
> > 
> > Jonathan Cameron (1):
> >   hw/cxl: Get Physical Port State - update for PCIe flit mode
> > 
> >  include/hw/cxl/cxl_port.h                   |  73 ++++++++
> >  include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
> >  include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
> >  hw/cxl/cxl-mailbox-utils.c                  | 183 ++++++++++++++++++--
> >  hw/pci-bridge/cxl_downstream.c              |   9 +
> >  hw/pci-bridge/cxl_upstream.c                |   1 +
> >  6 files changed, 268 insertions(+), 12 deletions(-)
> >  create mode 100644 include/hw/cxl/cxl_port.h
> >  create mode 100644 include/hw/pci-bridge/cxl_downstream_port.h
> > 
> > -- 
> > 2.51.0  
> 
> 
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support.
  2026-02-23 11:01     ` Jonathan Cameron
@ 2026-02-23 11:28       ` Jonathan Cameron
  0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-23 11:28 UTC (permalink / raw)
  To: Jonathan Cameron via qemu development
  Cc: Jonathan Cameron, Michael S. Tsirkin, Arpit Kumar, linuxarm,
	linux-cxl, Ravi Shankar, Marcel Apfelbaum, Michael Roth

On Mon, 23 Feb 2026 11:01:09 +0000
Jonathan Cameron via qemu development <qemu-devel@nongnu.org> wrote:

> On Fri, 20 Feb 2026 07:58:49 -0500
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Feb 04, 2026 at 05:32:20PM +0000, Jonathan Cameron wrote:  
> > > Changes since v4:
> > > https://lore.kernel.org/qemu-devel/20250916080736.1266083-1-arpit1.kumar@samsung.com/
> > > - Dropped initial refactor. Reason being that it is not static enough
> > >   for caching at boot to be appropriate.  Kept the spec update part
> > >   of this.
> > > - Added a patch to make sure the new flip mode stuff is reported in
> > >   the Get Physical Port State command.
> > > - Rebased Arpit's Physical Control Control FMAPI Command given drop
> > >   of the major refactor from v4 patch 1.
> > > 
> > > I had taken this into my cxl staging tree thinking it only needed a few
> > > minor tweaks.  Then whilst testing I realized it didn't work with hotplug
> > > and that made me consider if Arpit's original approach made sense.
> > > 
> > > So this is my proposal on how to take this forwards. Note that this is
> > > not ready for merge (probably) just yet as I'd like Arpit to take a
> > > look at the changes.    
> > 
> > I'd appreciate it if you add rfc in the subject in such cases.
> > Thanks!  
> 
> Will do.
> 
> Arpit is happy with this, so now I think main thing it needs is review of the
> PCI interactions and the resets.  They seem fine to me but I'm not that
> familiar with that stuff so am relying on PCI / reset experts.
> 
> That part is all in patch 3.  If you are happy with that part, then I'm
> very much in favor of merging this.

I caught up with rest of the list and see this was in your pull request.
All good then!

Thanks,

Jonathan

> 
> Jonathan
> 
> >   
> > >  I went through a version that had major refactors
> > > to push the logic of building the records to the ports themselves, but
> > > in the end don't think that brings enough benefits for the complexity.
> > > 
> > > Based on:
> > > https://lore.kernel.org/qemu-devel/20260204170936.43959-1-Jonathan.Cameron@huawei.com/T/#t
> > > (with all it's precursors, though hopefully they will all be in Michael's
> > > next pull request)
> > > 
> > > I'll note this is an enormous foot gun as it lets you effectively trigger
> > > surprise device resets.  However, it's only accessible if you are using
> > > a configuration with the fabric management parts of the CXL emulation.
> > > For now that is a switch-cci (MCTP over USB support is near the top
> > > of my list of things to get ready for upstram.  I tested this with a
> > > custom driver and if nothing else it exposed some gaps in Linux's
> > > ability to rescan PCI buses after a perst event (even with drivers
> > > unbound etc to make it safe).
> > > 
> > > Original cover letter:
> > > 
> > > This patch series refactor existing support for Identify Switch Device
> > > and Get Physical Port State by utilizing physical ports (USP & DSP)
> > > information stored during enumeration.
> > > 
> > > Additionally, it introduces new support for Physical Port Control
> > > of Physical Switch Command Set as per CXL spec r3.2 Section 7.6.7.1.3.
> > > It primarily constitutes two logic:
> > >     -Assert-Deassert PERST: Assert PERST involves physical port to be in
> > >      hold reset phase for minimum 100ms. No other physical port control
> > >      request are entertained until Deassert PERST command for the given
> > >      port is issued.
> > >     -Reset PPB: cold reset of physical port (completing enter->hold->exit
> > >      phases).
> > > 
> > > Tested using libcxl-mi interface[1]:
> > > All active ports and all opcodes per active port is tested. Also, tested
> > > against possible edge cases manually since the interface currently dosen't
> > > support run time input.
> > > 
> > > Typical Qemu topology
> > > (1 USP + 3 DSP's in a switch with 2 CXLType3 devices connected to the 2 DSP's):
> > > FM="-object memory-backend-file,id=cxl-mem1,mem-path=$TMP_DIR/t3_cxl1.raw,size=256M \
> > >     -object memory-backend-file,id=cxl-lsa1,mem-path=$TMP_DIR/t3_lsa1.raw,size=1M \
> > >     -object memory-backend-file,id=cxl-mem2,mem-path=$TMP_DIR/t3_cxl2.raw,size=512M \
> > >     -object memory-backend-file,id=cxl-lsa2,mem-path=$TMP_DIR/t3_lsa2.raw,size=512M \
> > >     -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1,hdm_for_passthrough=true \
> > >     -device cxl-rp,port=0,bus=cxl.1,id=cxl_rp_port0,chassis=0,slot=2 \
> > >     -device cxl-upstream,port=2,sn=1234,bus=cxl_rp_port0,id=us0,addr=0.0,multifunction=on, \
> > >     -device cxl-switch-mailbox-cci,bus=cxl_rp_port0,addr=0.1,target=us0 \
> > >     -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
> > >     -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
> > >     -device cxl-downstream,port=3,bus=us0,id=swport2,chassis=0,slot=6 \
> > >     -device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 \
> > >     -device cxl-type3,bus=swport2,memdev=cxl-mem2,id=cxl-pmem2,lsa=cxl-lsa2,sn=4 \
> > >     -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \
> > >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
> > >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1 \
> > >     -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem2 \
> > >     -device virtio-rng-pci,bus=swport1"
> > > 
> > > Tested multiple Qemu topologies:
> > >         -without any devices connected to downstream ports.
> > >         -with virtio-rng-pci devices connected to downstream ports.
> > >         -with CXLType3 devices connected to downstream ports.
> > >         -with different unique values of ports (both upstream and downstream).
> > > 
> > > Changes from v3 (https://lore.kernel.org/qemu-devel/20250909160316.00000190@huawei.com/T/):
> > >         -Namespaced the defines with cleaner prefix for Get Physical Port State 
> > >          Port Information Block members.
> > >         -switch CCI implementation instead of switch FM interface as per
> > >          Jonathan's review comments, hence moved perst members initializations
> > >          from: cxl_initialize_usp_mctpcci() -> cxl_initialize_mailbox_swcci().
> > > 
> > > [1] https://github.com/computexpresslink/libcxlmi/commit/35fe68bd9a31469f832a87694d7b18d2d50be5b8
> > > 
> > > 
> > > Arpit Kumar (2):
> > >   hw/cxl: Physical Port Info FMAPI - update to current spec and add
> > >     defines.
> > >   hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h)
> > > 
> > > Jonathan Cameron (1):
> > >   hw/cxl: Get Physical Port State - update for PCIe flit mode
> > > 
> > >  include/hw/cxl/cxl_port.h                   |  73 ++++++++
> > >  include/hw/pci-bridge/cxl_downstream_port.h |  12 ++
> > >  include/hw/pci-bridge/cxl_upstream_port.h   |   2 +
> > >  hw/cxl/cxl-mailbox-utils.c                  | 183 ++++++++++++++++++--
> > >  hw/pci-bridge/cxl_downstream.c              |   9 +
> > >  hw/pci-bridge/cxl_upstream.c                |   1 +
> > >  6 files changed, 268 insertions(+), 12 deletions(-)
> > >  create mode 100644 include/hw/cxl/cxl_port.h
> > >  create mode 100644 include/hw/pci-bridge/cxl_downstream_port.h
> > > 
> > > -- 
> > > 2.51.0    
> > 
> > 
> >   
> 
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-02-23 11:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <CGME20260212151259epcas5p2364104fe9a48c7673863df040dacbfef@epcas5p2.samsung.com>
2026-02-04 17:32 ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Jonathan Cameron
2026-02-04 17:32   ` [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines Jonathan Cameron
2026-02-12 15:22     ` Arpit Kumar
2026-02-04 17:32   ` [PATCH qemu v5 2/3] hw/cxl: Get Physical Port State - update for PCIe flit mode Jonathan Cameron
2026-02-04 17:32   ` [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h) Jonathan Cameron
2026-02-12 15:25     ` Arpit Kumar
2026-02-12 15:12   ` [PATCH qemu v5 0/3] hw/cxl: FM-API Physical Switch Command Set Support Arpit Kumar
2026-02-20 12:58   ` Michael S. Tsirkin
2026-02-23 11:01     ` Jonathan Cameron
2026-02-23 11:28       ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox