From nobody Sat Feb 7 08:55:06 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1770226405; cv=none; d=zohomail.com; s=zohoarc; b=TITaNBbLpaq0gEke5qV7SdSFtOFXjK5aA6YwEJGyK6f0VJQXq8uojYXzTfh03DY89IZfod6MPeEEUowmQK7zxjV22OcTIAFmx6wtbOMU+WO0BNfSnbWzQu2LxE0+mWAqD2sLVbGiDWrtgCbTFxWcf0X4JwplVqU/+hHaGbbxhKM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770226405; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=XdoEK8xZfC8fLTddYnPLKBxPIj3WpbgcrFk0vjF8Rkg=; b=i6cwzrKdQKgb8XM2JYBAd2uMyYrDdPlZ+tDLoW+fGiop110KPVEtS2p/W9s45Rr5wf/uqIhAnzjYhlfFlEcethAtp+9NB36PjaXFvcnkIYUG81+mWD43aUMEwcdQaf2m/RnwI5+jlkuT+KST+c90sCR2ESheI1sIe0NSfhsuOF4= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1770226405175625.7102017278; Wed, 4 Feb 2026 09:33:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vngkP-00070u-U0; Wed, 04 Feb 2026 12:33:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vngkO-00070l-JS for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:33:00 -0500 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vngkM-0005Ll-Ql for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:33:00 -0500 Received: from mail.maildlp.com (unknown [172.18.224.83]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4f5nTy6KBXzJ46FB; Thu, 5 Feb 2026 01:32:06 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 3CE0D40569; Thu, 5 Feb 2026 01:32:56 +0800 (CST) Received: from SecurePC-101-06.huawei.com (10.122.19.247) by dubpeml500005.china.huawei.com (7.214.145.207) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 4 Feb 2026 17:32:55 +0000 To: Michael Tsirkin , , Arpit Kumar CC: , , Ravi Shankar , Marcel Apfelbaum , Michael Roth Subject: [PATCH qemu v5 1/3] hw/cxl: Physical Port Info FMAPI - update to current spec and add defines. Date: Wed, 4 Feb 2026 17:32:21 +0000 Message-ID: <20260204173223.44122-2-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> References: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.122.19.247] X-ClientProxiedBy: lhrpeml500011.china.huawei.com (7.191.174.215) To dubpeml500005.china.huawei.com (7.214.145.207) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=jonathan.cameron@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jonathan Cameron From: Jonathan Cameron via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1770226407944154100 Content-Type: text/plain; charset="utf-8" From: Arpit Kumar 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 Co-developed-by: Jonathan Cameron Signed-off-by: Jonathan Cameron --- 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 For= mat */ +#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 s= truct cxl_cmd *cmd, } QEMU_PACKED *in; =20 /* - * 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 s= truct cxl_cmd *cmd, if (port_dev) { /* DSP */ PCIDevice *ds_dev =3D pci_bridge_get_sec_bus(PCI_BRIDGE(port_d= ev)) ->devices[0]; - port->config_state =3D 3; + port->config_state =3D CXL_PORT_CONFIG_STATE_DSP; if (ds_dev) { if (object_dynamic_cast(OBJECT(ds_dev), TYPE_CXL_TYPE3)) { - port->connected_device_type =3D 5; /* Assume MLD for n= ow */ + /* Assume MLD for now */ + port->connected_device_type =3D + CXL_PORT_CONNECTED_DEV_TYPE_3_MLD; } else { - port->connected_device_type =3D 1; + port->connected_device_type =3D + CXL_PORT_CONNECTED_DEV_TYPE_PCIE; + port->connected_device_mode =3D + CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN; + } } else { - port->connected_device_type =3D 0; + port->connected_device_type =3D CXL_PORT_CONNECTED_DEV_TYP= E_NONE; + port->connected_device_mode =3D + CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN; } port->supported_ld_count =3D 3; } else if (usp->port =3D=3D in->ports[i]) { /* USP */ port_dev =3D PCI_DEVICE(usp); - port->config_state =3D 4; - port->connected_device_type =3D 0; + port->config_state =3D CXL_PORT_CONFIG_STATE_USP; + port->connected_device_type =3D 0; /* Reserved for USP */ + port->connected_device_mode =3D 0; /* Reserved for USP */ } else { return CXL_MBOX_INVALID_INPUT; } @@ -667,8 +677,7 @@ static CXLRetCode cmd_get_physical_port_state(const str= uct cxl_cmd *cmd, port->ltssm_state =3D 0x7; port->first_lane_num =3D 0; port->link_state =3D 0; - port->port_cxl_version_bitmask =3D 0x2; - port->connected_device_cxl_version =3D 0x2; + port->supported_cxl_mode_bitmask =3D CXL_PORT_SUPPORTS_68B_VH; } =20 pl_size =3D sizeof(*out) + sizeof(*out->ports) * in->num_ports; --=20 2.51.0 From nobody Sat Feb 7 08:55:06 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1770226423; cv=none; d=zohomail.com; s=zohoarc; b=KwIWtAB2EClDg8FWdsSWLJBSWCegY6P5Yc0UDYwOMSNDoeTs+/k6Dp1y/8PiJ23qRrEKQtoPDMnOM6cvrQlsjTGZpH++nLaXskUGKX+q6UlJF6dfcASAJ3lcA0d+nliMu2Tw1AamI4OwnWTpGshpPZ+FTqP8Mamraiff09YujVY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770226423; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=BhZHOq1/iyOAkpBxYww/WWqSyiBRgh597mSXBHBJ9Ts=; b=W0ZQigDmG5eVB93TMbODVEBm8pEAeW07D9mcU9NTKjTomwyuceBMS+8Y4K9w/UHUVefd0YyLny6a84PHkRQ5vlqk3DvsJSxhxoqnaL+x/WN8eLHjON73mbe2RJABNGC9OC27Q18T31x0MZCcSDS7z0uvpKoxPISHPihtkpZkPHs= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1770226423027683.8800300864228; Wed, 4 Feb 2026 09:33:43 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vngkw-0007cR-C9; Wed, 04 Feb 2026 12:33:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vngkt-0007Sd-Jt for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:33:31 -0500 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vngkr-0005es-Mg for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:33:31 -0500 Received: from mail.maildlp.com (unknown [172.18.224.150]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4f5nVZ1RWVzJ46BN; Thu, 5 Feb 2026 01:32:38 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 883624056A; Thu, 5 Feb 2026 01:33:27 +0800 (CST) Received: from SecurePC-101-06.huawei.com (10.122.19.247) by dubpeml500005.china.huawei.com (7.214.145.207) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 4 Feb 2026 17:33:26 +0000 To: Michael Tsirkin , , Arpit Kumar CC: , , Ravi Shankar , Marcel Apfelbaum , Michael Roth Subject: [PATCH qemu v5 2/3] hw/cxl: Get Physical Port State - update for PCIe flit mode Date: Wed, 4 Feb 2026 17:32:22 +0000 Message-ID: <20260204173223.44122-3-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> References: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.122.19.247] X-ClientProxiedBy: lhrpeml500011.china.huawei.com (7.191.174.215) To dubpeml500005.china.huawei.com (7.214.145.207) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=jonathan.cameron@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jonathan Cameron From: Jonathan Cameron via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1770226426109158500 Content-Type: text/plain; charset="utf-8" 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 --- 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 st= ruct cxl_cmd *cmd, port->config_state =3D 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 =3D port_dev->config_read(port_dev, + port_dev->exp.exp_cap + PCI_EXP_LNKSTA2, + sizeof(lnksta2)); + /* Assume MLD for now */ port->connected_device_type =3D CXL_PORT_CONNECTED_DEV_TYPE_3_MLD; + if (lnksta2 & PCI_EXP_LNKSTA2_FLIT) { + port->connected_device_mode =3D + CXL_PORT_CONNECTED_DEV_MODE_256B; + } else { + port->connected_device_mode =3D + CXL_PORT_CONNECTED_DEV_MODE_68B_VH; + } } else { port->connected_device_type =3D CXL_PORT_CONNECTED_DEV_TYPE_PCIE; @@ -642,12 +659,17 @@ static CXLRetCode cmd_get_physical_port_state(const s= truct cxl_cmd *cmd, port->connected_device_mode =3D CXL_PORT_CONNECTED_DEV_MODE_NOT_CXL_OR_DISCONN; } + /* DSP currently always support modes implemented in QEMU */ + port->supported_cxl_mode_bitmask =3D CXL_PORT_SUPPORTS_68B_VH | + CXL_PORT_SUPPORTS_256B; port->supported_ld_count =3D 3; } else if (usp->port =3D=3D in->ports[i]) { /* USP */ port_dev =3D PCI_DEVICE(usp); port->config_state =3D CXL_PORT_CONFIG_STATE_USP; port->connected_device_type =3D 0; /* Reserved for USP */ port->connected_device_mode =3D 0; /* Reserved for USP */ + port->supported_cxl_mode_bitmask =3D 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 str= uct cxl_cmd *cmd, /* TODO: Track down if we can get the rest of the info */ port->ltssm_state =3D 0x7; port->first_lane_num =3D 0; - port->link_state =3D 0; - port->supported_cxl_mode_bitmask =3D CXL_PORT_SUPPORTS_68B_VH; } =20 pl_size =3D sizeof(*out) + sizeof(*out->ports) * in->num_ports; --=20 2.51.0 From nobody Sat Feb 7 08:55:06 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1770226451; cv=none; d=zohomail.com; s=zohoarc; b=BgZl2/wMa8ReDRn/+w3zllPVUCn6SSXCYII4FMhz08g0ugDc4d9VNiM35/nNrcZAmE2AevvLm6TDhfRsdkWCM8NyJ2460PVIMOALUz2EmZpxs09p6KF4QkeKkxShS3G+DM9SW0wyoLajth21wf8LgsKmNFSPPhMHA4Tr3NwW+tU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770226451; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=cslwn0iI9M22XUAOydGGruLz5CmBI4zzTgz1NhIL0uE=; b=HxkzIRd6Ml6Iv1wvUICKp+x3TGAyfFkhJm19EQGdomIBXhamqwItNMNIEPzyittNbZCw/bCE7CjbhhYP4bEUBc2IpsewFfW1n4oo7S+8mWFlsvpJuKRlBaVFOJWCT2TqyGjuyd3IOsnPUo/6KZmPJbvXtrd3Omw8mF7Mn66eVdI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 177022645163030.632824285747688; Wed, 4 Feb 2026 09:34:11 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vnglP-0008Fj-GW; Wed, 04 Feb 2026 12:34:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vnglO-0008FK-45 for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:34:02 -0500 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vnglL-0005sx-Qt for qemu-devel@nongnu.org; Wed, 04 Feb 2026 12:34:01 -0500 Received: from mail.maildlp.com (unknown [172.18.224.150]) by frasgout.his.huawei.com (SkyGuard) with ESMTPS id 4f5nW90nMTzJ46Zw; Thu, 5 Feb 2026 01:33:09 +0800 (CST) Received: from dubpeml500005.china.huawei.com (unknown [7.214.145.207]) by mail.maildlp.com (Postfix) with ESMTPS id 70FEC4056A; Thu, 5 Feb 2026 01:33:58 +0800 (CST) Received: from SecurePC-101-06.huawei.com (10.122.19.247) by dubpeml500005.china.huawei.com (7.214.145.207) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 4 Feb 2026 17:33:57 +0000 To: Michael Tsirkin , , Arpit Kumar CC: , , Ravi Shankar , Marcel Apfelbaum , Michael Roth Subject: [PATCH qemu v5 3/3] hw/cxl: Add Physical Port Control FMAPI Command (Opcode 5102h) Date: Wed, 4 Feb 2026 17:32:23 +0000 Message-ID: <20260204173223.44122-4-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> References: <20260204173223.44122-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.122.19.247] X-ClientProxiedBy: lhrpeml500011.china.huawei.com (7.191.174.215) To dubpeml500005.china.huawei.com (7.214.145.207) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=jonathan.cameron@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jonathan Cameron From: Jonathan Cameron via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1770226453753158500 Content-Type: text/plain; charset="utf-8" From: Arpit Kumar 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 Co-developed-by: Jonathan Cameron Signed-off-by: Jonathan Cameron --- 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 =20 +#include "qemu/thread.h" + /* CXL r3.2 Table 7-19: Get Physical Port State Port Information Block For= mat */ #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) =20 +#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_TI= ME_MS; +} + #endif /* CXL_PORT_H */ diff --git a/include/hw/pci-bridge/cxl_downstream_port.h b/include/hw/pci-b= ridge/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-bri= dge/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" =20 typedef struct CXLUpstreamPort { /*< private >*/ @@ -12,6 +13,7 @@ typedef struct CXLUpstreamPort { /*< public >*/ CXLComponentState cxl_cstate; CXLCCI swcci; + CXLPhyPortPerst perst; =20 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 =3D 0x51, #define IDENTIFY_SWITCH_DEVICE 0x0 #define GET_PHYSICAL_PORT_STATE 0x1 + #define PHYSICAL_PORT_CONTROL 0x2 TUNNEL =3D 0x53, #define MANAGEMENT_COMMAND 0x0 FMAPI_DCD_MGMT =3D 0x56, @@ -616,6 +618,7 @@ static CXLRetCode cmd_get_physical_port_state(const str= uct 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; =20 port =3D &out->ports[i]; @@ -663,6 +666,7 @@ static CXLRetCode cmd_get_physical_port_state(const str= uct cxl_cmd *cmd, port->supported_cxl_mode_bitmask =3D CXL_PORT_SUPPORTS_68B_VH | CXL_PORT_SUPPORTS_256B; port->supported_ld_count =3D 3; + perst =3D cxl_dsp_get_perst(CXL_DSP(port_dev)); } else if (usp->port =3D=3D in->ports[i]) { /* USP */ port_dev =3D PCI_DEVICE(usp); port->config_state =3D CXL_PORT_CONFIG_STATE_USP; @@ -670,6 +674,7 @@ static CXLRetCode cmd_get_physical_port_state(const str= uct cxl_cmd *cmd, port->connected_device_mode =3D 0; /* Reserved for USP */ port->supported_cxl_mode_bitmask =3D CXL_PORT_SUPPORTS_68B_VH | (CXL_USP(usp)->flitmode ? CXL_PORT_SUPPORTS_256B : 0); + perst =3D &CXL_USP(usp)->perst; } else { return CXL_MBOX_INVALID_INPUT; } @@ -698,6 +703,7 @@ static CXLRetCode cmd_get_physical_port_state(const str= uct cxl_cmd *cmd, /* TODO: Track down if we can get the rest of the info */ port->ltssm_state =3D 0x7; port->first_lane_num =3D 0; + port->link_state =3D perst ? CXL_PORT_LINK_STATE_FLAG_PERST_ASSERT= ED : 0; } =20 pl_size =3D sizeof(*out) + sizeof(*out->ports) * in->num_ports; @@ -706,6 +712,115 @@ static CXLRetCode cmd_get_physical_port_state(const s= truct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } =20 +static void *bg_assertcb(void *opaque) +{ + CXLPhyPortPerst *perst =3D opaque; + + /* holding reset phase for 100ms */ + while (perst->asrt_time--) { + usleep(1000); + } + perst->issued_assert_perst =3D 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 =3D false; + perst->asrt_time =3D 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 =3D 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 =3D 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 =3D (void *)payload_in; + + if (len_in < sizeof(*in)) { + return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + if (PCIE_PORT(pp)->port =3D=3D in->ppb_id) { + dev =3D PCI_DEVICE(pp); + perst =3D &pp->perst; + } else { + CXLDownstreamPort *dsp =3D + cxl_find_dsp_on_bus(&PCI_BRIDGE(pp)->sec_bus, in->ppb_id); + + if (!dsp) { + return CXL_MBOX_INVALID_INPUT; + } + dev =3D PCI_DEVICE(dsp); + perst =3D 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] = =3D { cmd_identify_switch_device, 0, 0 }, [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] =3D { "SWITCH_PHYSICAL_PORT= _STATS", cmd_get_physical_port_state, ~0, 0 }, + [PHYSICAL_SWITCH][PHYSICAL_PORT_CONTROL] =3D { "SWITCH_PHYSICAL_PORT_C= ONTROL", + cmd_physical_port_control, 2, 0 }, [TUNNEL][MANAGEMENT_COMMAND] =3D { "TUNNEL_MANAGEMENT_COMMAND", cmd_tunnel_management_cmd, ~0, 0 }, }; @@ -4618,6 +4735,19 @@ static void cxl_rebuild_cel(CXLCCI *cci) } } =20 +void cxl_init_physical_port_control(CXLPhyPortPerst *perst) +{ + qemu_mutex_init(&perst->lock); + perst->issued_assert_perst =3D 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 =3D ASSERT_WAIT_TIME_MS; +} + void cxl_init_cci(CXLCCI *cci, size_t payload_max) { cci->payload_max =3D 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" =20 typedef struct CXLDownstreamPort { @@ -24,6 +26,7 @@ typedef struct CXLDownstreamPort { =20 /*< public >*/ CXLComponentState cxl_cstate; + CXLPhyPortPerst perst; } CXLDownstreamPort; =20 #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); } =20 +CXLPhyPortPerst *cxl_dsp_get_perst(CXLDownstreamPort *dsp) +{ + return &dsp->perst; +} + static void cxl_dsp_reset(DeviceState *qdev) { PCIDevice *d =3D PCI_DEVICE(qdev); @@ -92,6 +100,7 @@ static void cxl_dsp_reset(DeviceState *qdev) pci_bridge_reset(qdev); =20 latch_registers(dsp); + cxl_init_physical_port_control(&dsp->perst); } =20 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); } =20 static void build_dvsecs(CXLUpstreamPort *usp) --=20 2.51.0