From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Arpit Kumar <arpit1.kumar@samsung.com>
Cc: <qemu-devel@nongnu.org>, <gost.dev@samsung.com>,
<linux-cxl@vger.kernel.org>, <nifan.cxl@gmail.com>,
<dave@stgolabs.net>, <vishak.g@samsung.com>,
<krish.reddy@samsung.com>, <a.manzanares@samsung.com>,
<alok.rathore@samsung.com>, <cpgs@samsung.com>
Subject: Re: [PATCH v2 2/2] hw/cxl: Add Physical Port Control (Opcode 5102h)
Date: Fri, 25 Jul 2025 15:59:12 +0100 [thread overview]
Message-ID: <20250725155912.0000551d@huawei.com> (raw)
In-Reply-To: <20250710144338.2839512-3-arpit1.kumar@samsung.com>
On Thu, 10 Jul 2025 20:13:38 +0530
Arpit Kumar <arpit1.kumar@samsung.com> wrote:
> -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>
Hi Arpit,
Minor comments inline.
We have plenty of time given where the qemu cycle is, so no huge rush
for a v3.
Jonathan
> +static struct PCIDevice *cxl_find_port_dev(uint8_t pn, CXLCCI *cci)
> +{
> + CXLUpstreamPort *pp = CXL_USP(cci->d);
> + PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
> +
> + if (pp->pports.pport_info[pn].current_port_config_state ==
> + CXL_PORT_CONFIG_STATE_USP) {
> + PCIDevice *usp_dev = pci_bridge_get_device(bus);
> + return usp_dev;
As below.
> + }
> +
> + if (pp->pports.pport_info[pn].current_port_config_state ==
> + CXL_PORT_CONFIG_STATE_DSP) {
> + PCIDevice *dsp_dev = pcie_find_port_by_pn(bus, pn);
> + return dsp_dev;
What benefit do we get from a local variable?
> + }
> + 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);
> + PCIDevice *dev;
> + uint8_t ret = CXL_MBOX_SUCCESS;
> +
> + 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;
> + }
> +
> + uint8_t pn = in->ppb_id;
Avoid inline declarations of local variables.
> + if (pp->pports.pport_info[pn].port_id != pn) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> +
> + dev = cxl_find_port_dev(pn, cci);
> + if (!dev) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> +
> + switch (in->ports_op) {
> + case 0:
> + ret = assert_perst(OBJECT(&dev->qdev), pn, pp);
> + break;
> + case 1:
> + ret = deassert_perst(OBJECT(&dev->qdev), pn, pp);
> + break;
> + case 2:
> + if (pp->pports.perst[pn].issued_assert_perst ||
> + pp->pports.perst[pn].asrt_time < ASSERT_WAIT_TIME_MS) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> + device_cold_reset(&dev->qdev);
> + break;
> + default:
> + return CXL_MBOX_INVALID_INPUT;
> + }
> + return ret;
> +}
> @@ -3810,4 +3932,17 @@ void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
> cci->intf = intf;
> cxl_init_cci(cci, payload_max);
> cxl_set_phy_port_info(cci);
> + /* physical port control */
> + CXLUpstreamPort *pp = CXL_USP(cci->d);
Still sticking to the old style c option of declarations at the top of the scope.
> + for (int i = 0; i < CXL_MAX_PHY_PORTS; i++) {
> + qemu_mutex_init(&pp->pports.perst[i].lock);
> + pp->pports.perst[i].issued_assert_perst = false;
> + /*
> + * Assert PERST involves physical port to be in
> + * hold reset phase for minimum 100ms. No other
> + * physcial port control requests are entertained
> + * until Deassert PERST command.
> + */
> + pp->pports.perst[i].asrt_time = ASSERT_WAIT_TIME_MS;
> + }
> }
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 1fa6cf7536..bb47e671eb 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -128,6 +128,7 @@
> (1 << 16))
>
> #define CXL_MAX_PHY_PORTS 256
> +#define ASSERT_WAIT_TIME_MS 100 /* Assert - Deassert PERST */
>
> #define LINK_STATE_FLAG_LANE_REVERSED BIT(0)
> #define LINK_STATE_FLAG_PERST_ASSERTED BIT(1)
> @@ -203,10 +204,19 @@ struct cxl_phy_port_info {
> uint8_t supported_ld_count;
> } QEMU_PACKED;
>
> +/* Assert - Deassert PERST */
> +struct pperst {
Prefix this name. pperst is a PCIE thing so it may otherwise end up confusing.
> + bool issued_assert_perst;
> + QemuMutex lock;
Good practice to add a comment to say exactly what data this lock is protecting.
> + uint64_t asrt_time;
> + QemuThread asrt_thread; /* thread for 100ms delay */
> +};
> +
> struct phy_port {
> uint8_t num_ports;
> uint8_t active_port_bitmask[0x20];
> struct cxl_phy_port_info pport_info[CXL_MAX_PHY_PORTS];
> + struct pperst perst[CXL_MAX_PHY_PORTS];
> };
>
> /* CXL r3.1 Table 8-34: Command Return Codes */
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron via <qemu-devel@nongnu.org>
To: Arpit Kumar <arpit1.kumar@samsung.com>
Cc: <qemu-devel@nongnu.org>, <gost.dev@samsung.com>,
<linux-cxl@vger.kernel.org>, <nifan.cxl@gmail.com>,
<dave@stgolabs.net>, <vishak.g@samsung.com>,
<krish.reddy@samsung.com>, <a.manzanares@samsung.com>,
<alok.rathore@samsung.com>, <cpgs@samsung.com>
Subject: Re: [PATCH v2 2/2] hw/cxl: Add Physical Port Control (Opcode 5102h)
Date: Fri, 25 Jul 2025 15:59:12 +0100 [thread overview]
Message-ID: <20250725155912.0000551d@huawei.com> (raw)
In-Reply-To: <20250710144338.2839512-3-arpit1.kumar@samsung.com>
On Thu, 10 Jul 2025 20:13:38 +0530
Arpit Kumar <arpit1.kumar@samsung.com> wrote:
> -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>
Hi Arpit,
Minor comments inline.
We have plenty of time given where the qemu cycle is, so no huge rush
for a v3.
Jonathan
> +static struct PCIDevice *cxl_find_port_dev(uint8_t pn, CXLCCI *cci)
> +{
> + CXLUpstreamPort *pp = CXL_USP(cci->d);
> + PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
> +
> + if (pp->pports.pport_info[pn].current_port_config_state ==
> + CXL_PORT_CONFIG_STATE_USP) {
> + PCIDevice *usp_dev = pci_bridge_get_device(bus);
> + return usp_dev;
As below.
> + }
> +
> + if (pp->pports.pport_info[pn].current_port_config_state ==
> + CXL_PORT_CONFIG_STATE_DSP) {
> + PCIDevice *dsp_dev = pcie_find_port_by_pn(bus, pn);
> + return dsp_dev;
What benefit do we get from a local variable?
> + }
> + 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);
> + PCIDevice *dev;
> + uint8_t ret = CXL_MBOX_SUCCESS;
> +
> + 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;
> + }
> +
> + uint8_t pn = in->ppb_id;
Avoid inline declarations of local variables.
> + if (pp->pports.pport_info[pn].port_id != pn) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> +
> + dev = cxl_find_port_dev(pn, cci);
> + if (!dev) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> +
> + switch (in->ports_op) {
> + case 0:
> + ret = assert_perst(OBJECT(&dev->qdev), pn, pp);
> + break;
> + case 1:
> + ret = deassert_perst(OBJECT(&dev->qdev), pn, pp);
> + break;
> + case 2:
> + if (pp->pports.perst[pn].issued_assert_perst ||
> + pp->pports.perst[pn].asrt_time < ASSERT_WAIT_TIME_MS) {
> + return CXL_MBOX_INTERNAL_ERROR;
> + }
> + device_cold_reset(&dev->qdev);
> + break;
> + default:
> + return CXL_MBOX_INVALID_INPUT;
> + }
> + return ret;
> +}
> @@ -3810,4 +3932,17 @@ void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
> cci->intf = intf;
> cxl_init_cci(cci, payload_max);
> cxl_set_phy_port_info(cci);
> + /* physical port control */
> + CXLUpstreamPort *pp = CXL_USP(cci->d);
Still sticking to the old style c option of declarations at the top of the scope.
> + for (int i = 0; i < CXL_MAX_PHY_PORTS; i++) {
> + qemu_mutex_init(&pp->pports.perst[i].lock);
> + pp->pports.perst[i].issued_assert_perst = false;
> + /*
> + * Assert PERST involves physical port to be in
> + * hold reset phase for minimum 100ms. No other
> + * physcial port control requests are entertained
> + * until Deassert PERST command.
> + */
> + pp->pports.perst[i].asrt_time = ASSERT_WAIT_TIME_MS;
> + }
> }
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 1fa6cf7536..bb47e671eb 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -128,6 +128,7 @@
> (1 << 16))
>
> #define CXL_MAX_PHY_PORTS 256
> +#define ASSERT_WAIT_TIME_MS 100 /* Assert - Deassert PERST */
>
> #define LINK_STATE_FLAG_LANE_REVERSED BIT(0)
> #define LINK_STATE_FLAG_PERST_ASSERTED BIT(1)
> @@ -203,10 +204,19 @@ struct cxl_phy_port_info {
> uint8_t supported_ld_count;
> } QEMU_PACKED;
>
> +/* Assert - Deassert PERST */
> +struct pperst {
Prefix this name. pperst is a PCIE thing so it may otherwise end up confusing.
> + bool issued_assert_perst;
> + QemuMutex lock;
Good practice to add a comment to say exactly what data this lock is protecting.
> + uint64_t asrt_time;
> + QemuThread asrt_thread; /* thread for 100ms delay */
> +};
> +
> struct phy_port {
> uint8_t num_ports;
> uint8_t active_port_bitmask[0x20];
> struct cxl_phy_port_info pport_info[CXL_MAX_PHY_PORTS];
> + struct pperst perst[CXL_MAX_PHY_PORTS];
> };
>
> /* CXL r3.1 Table 8-34: Command Return Codes */
next prev parent reply other threads:[~2025-07-25 14:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20250710144348epcas5p1842ad24e3de24dd7048b0db9dfbe6455@epcas5p1.samsung.com>
2025-07-10 14:43 ` [PATCH v2 0/2] FM-API Physical switch command set support Arpit Kumar
2025-07-10 14:43 ` [PATCH v2 1/2] hw/cxl: Refactored Identify Switch Device & Get Physical Port State Arpit Kumar
2025-07-25 14:54 ` Jonathan Cameron
2025-07-25 14:54 ` Jonathan Cameron via
2025-07-29 12:58 ` Arpit Kumar
2025-07-10 14:43 ` [PATCH v2 2/2] hw/cxl: Add Physical Port Control (Opcode 5102h) Arpit Kumar
2025-07-25 14:59 ` Jonathan Cameron [this message]
2025-07-25 14:59 ` Jonathan Cameron via
2025-07-29 13:03 ` Arpit Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250725155912.0000551d@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=a.manzanares@samsung.com \
--cc=alok.rathore@samsung.com \
--cc=arpit1.kumar@samsung.com \
--cc=cpgs@samsung.com \
--cc=dave@stgolabs.net \
--cc=gost.dev@samsung.com \
--cc=krish.reddy@samsung.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nifan.cxl@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=vishak.g@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.