[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 10/17] hw/cxl: Implement Physical Ports status retrieval
|
From: |
Jonathan Cameron |
|
Subject: |
[PATCH v2 10/17] hw/cxl: Implement Physical Ports status retrieval |
|
Date: |
Mon, 23 Oct 2023 17:07:59 +0100 |
Add this command for both the Switch CCI in switch upstream ports.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
v2:
- Fix wrong size of message.
- Fill in downstream connected device with correct device types.
Note intially all emulated type 3 devices are considered MLDs.
---
hw/cxl/cxl-mailbox-utils.c | 128 +++++++++++++++++++++++++++++++++++++
1 file changed, 128 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 6ada49d37c..de63fc1a28 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -72,6 +72,7 @@ enum {
#define CLEAR_POISON 0x2
PHYSICAL_SWITCH = 0x51,
#define IDENTIFY_SWITCH_DEVICE 0x0
+ #define GET_PHYSICAL_PORT_STATE 0x1
};
@@ -320,6 +321,131 @@ static CXLRetCode cmd_identify_switch_device(const struct
cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+
+/* CXL r3.0 Section 7.6.7.1.2: Get Physical Port State (Opcode 5101h) */
+static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ /* CXL r3.0 Table 7-18: Get Physical Port State Request Payload */
+ struct cxl_fmapi_get_phys_port_state_req_pl {
+ uint8_t num_ports;
+ uint8_t ports[];
+ } QEMU_PACKED *in;
+
+ /*
+ * CXL r3.0 Table 7-20: 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 rsv1;
+ uint8_t connected_device_type;
+ uint8_t port_cxl_version_bitmask;
+ uint8_t max_link_width;
+ uint8_t negotiated_link_width;
+ uint8_t supported_link_speeds_vector;
+ uint8_t max_link_speed;
+ uint8_t current_link_speed;
+ uint8_t ltssm_state;
+ uint8_t first_lane_num;
+ uint16_t link_state;
+ uint8_t supported_ld_count;
+ } QEMU_PACKED;
+
+ /* CXL r3.0 Table 7-19: Get Physical Port State Response Payload */
+ struct cxl_fmapi_get_phys_port_state_resp_pl {
+ uint8_t num_ports;
+ uint8_t rsv1[3];
+ struct cxl_fmapi_port_state_info_block ports[];
+ } QEMU_PACKED *out;
+ PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
+ PCIEPort *usp = PCIE_PORT(cci->d);
+ size_t pl_size;
+ int i;
+
+ in = (struct cxl_fmapi_get_phys_port_state_req_pl *)payload_in;
+ out = (struct cxl_fmapi_get_phys_port_state_resp_pl *)payload_out;
+
+ /* Check if what was requested can fit */
+ if (sizeof(*out) + sizeof(*out->ports) * in->num_ports > cci->payload_max)
{
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ /* For success there should be a match for each requested */
+ out->num_ports = in->num_ports;
+
+ for (i = 0; i < in->num_ports; i++) {
+ struct cxl_fmapi_port_state_info_block *port;
+ /* First try to match on downstream port */
+ PCIDevice *port_dev;
+ uint16_t lnkcap, lnkcap2, lnksta;
+
+ port = &out->ports[i];
+
+ port_dev = pcie_find_port_by_pn(bus, in->ports[i]);
+ if (port_dev) { /* DSP */
+ PCIDevice *ds_dev = pci_bridge_get_sec_bus(PCI_BRIDGE(port_dev))
+ ->devices[0];
+ port->config_state = 3;
+ if (ds_dev) {
+ if (object_dynamic_cast(OBJECT(ds_dev), TYPE_CXL_TYPE3)) {
+ port->connected_device_type = 5; /* Assume MLD for now */
+ } else {
+ port->connected_device_type = 1;
+ }
+ } else {
+ port->connected_device_type = 0;
+ }
+ 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;
+ } else {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ port->port_id = in->ports[i];
+ /* Information on status of this port in lnksta, lnkcap */
+ if (!port_dev->exp.exp_cap) {
+ return CXL_MBOX_INTERNAL_ERROR;
+ }
+ lnksta = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap + PCI_EXP_LNKSTA,
+ sizeof(lnksta));
+ lnkcap = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap + PCI_EXP_LNKCAP,
+ sizeof(lnkcap));
+ lnkcap2 = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap +
PCI_EXP_LNKCAP2,
+ sizeof(lnkcap2));
+
+ port->max_link_width = (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4;
+ port->negotiated_link_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> 4;
+ /* No definition for SLS field in linux/pci_regs.h */
+ port->supported_link_speeds_vector = (lnkcap2 & 0xFE) >> 1;
+ port->max_link_speed = lnkcap & PCI_EXP_LNKCAP_SLS;
+ port->current_link_speed = lnksta & PCI_EXP_LNKSTA_CLS;
+ /* 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->port_cxl_version_bitmask = 0x2;
+ port->connected_device_cxl_version = 0x2;
+ }
+
+ pl_size = sizeof(*out) + sizeof(*out->ports) * in->num_ports;
+ *len_out = pl_size;
+
+ return CXL_MBOX_SUCCESS;
+}
+
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -881,6 +1007,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
[LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
[PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = { "IDENTIFY_SWITCH_DEVICE",
cmd_identify_switch_device, 0, 0 },
+ [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = {
"SWITCH_PHYSICAL_PORT_STATS",
+ cmd_get_physical_port_state, ~0, 0 },
};
int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
--
2.39.2
- [PATCH v2 00/17] QEMU: CXL mailbox rework and features (Part 1), Jonathan Cameron, 2023/10/23
- [PATCH v2 01/17] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant, Jonathan Cameron, 2023/10/23
- [PATCH v2 02/17] hw/cxl/mbox: Split mailbox command payload into separate input and output, Jonathan Cameron, 2023/10/23
- [PATCH v2 03/17] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState, Jonathan Cameron, 2023/10/23
- [PATCH v2 04/17] hw/cxl/mbox: Generalize the CCI command processing, Jonathan Cameron, 2023/10/23
- [PATCH v2 05/17] hw/pci-bridge/cxl_upstream: Move defintion of device to header., Jonathan Cameron, 2023/10/23
- [PATCH v2 06/17] hw/cxl: Add a switch mailbox CCI function, Jonathan Cameron, 2023/10/23
- [PATCH v2 07/17] hw/cxl/mbox: Add Information and Status / Identify command, Jonathan Cameron, 2023/10/23
- [PATCH v2 08/17] hw/cxl/mbox: Add Physical Switch Identify command., Jonathan Cameron, 2023/10/23
- [PATCH v2 09/17] hw/pci-bridge/cxl_downstream: Set default link width and link speed, Jonathan Cameron, 2023/10/23
- [PATCH v2 10/17] hw/cxl: Implement Physical Ports status retrieval,
Jonathan Cameron <=
- [PATCH v2 11/17] hw/cxl/mbox: Add support for background operations, Jonathan Cameron, 2023/10/23
- [PATCH v2 12/17] hw/cxl/mbox: Wire up interrupts for background completion, Jonathan Cameron, 2023/10/23
- [PATCH v2 13/17] hw/cxl: Add support for device sanitation, Jonathan Cameron, 2023/10/23
- [PATCH v2 14/17] hw/cxl/mbox: Add Get Background Operation Status Command, Jonathan Cameron, 2023/10/23
- [PATCH v2 15/17] hw/cxl/type3: Cleanup multiple CXL_TYPE3() calls in read/write functions, Jonathan Cameron, 2023/10/23
- [PATCH v2 16/17] hw/cxl: Add dummy security state get, Jonathan Cameron, 2023/10/23
- [PATCH v2 17/17] hw/cxl: Add tunneled command support to mailbox for switch cci., Jonathan Cameron, 2023/10/23