@@ -3775,6 +3775,79 @@ cxl_cmd_identify_get_persistent_only_size(struct cxl_cmd *cmd)
return cxl_capacity_to_bytes(c->persistent_capacity);
}
+CXL_EXPORT int
+cxl_cmd_identify_get_event_log_size(struct cxl_cmd *cmd,
+ enum cxl_identify_event event)
+{
+ struct cxl_cmd_identify *id =
+ (struct cxl_cmd_identify *)cmd->send_cmd->out.payload;
+ int rc = cxl_cmd_validate_status(cmd, CXL_MEM_COMMAND_ID_IDENTIFY);
+ if (rc)
+ return rc;
+
+ switch (event) {
+ case CXL_IDENTIFY_INFO:
+ return le16_to_cpu(id->info_event_log_size);
+ case CXL_IDENTIFY_WARN:
+ return le16_to_cpu(id->warning_event_log_size);
+ case CXL_IDENTIFY_FAIL:
+ return le16_to_cpu(id->failure_event_log_size);
+ case CXL_IDENTIFY_FATAL:
+ return le16_to_cpu(id->fatal_event_log_size);
+ default:
+ return -EINVAL;
+ }
+}
+
+CXL_EXPORT int cxl_cmd_identify_get_poison_list_max(struct cxl_cmd *cmd)
+{
+ unsigned int max_records = 0;
+ struct cxl_cmd_identify *id =
+ (struct cxl_cmd_identify *)cmd->send_cmd->out.payload;
+ int rc = cxl_cmd_validate_status(cmd, CXL_MEM_COMMAND_ID_IDENTIFY);
+ if (rc)
+ return rc;
+
+ for (int i = 0; i < 3; i++)
+ max_records += id->poison_list_max_mer[i] << (8 * i);
+
+ return max_records;
+}
+
+CXL_EXPORT int cxl_cmd_identify_get_inject_poison_limit(struct cxl_cmd *cmd)
+{
+ cmd_get_field_u16(cmd, identify, IDENTIFY, inject_poison_limit);
+}
+
+CXL_EXPORT int cxl_cmd_identify_injects_persistent_poison(struct cxl_cmd *cmd)
+{
+ cmd_get_field_u8_mask(
+ cmd, identify, IDENTIFY, poison_caps,
+ CXL_CMD_IDENTIFY_POISON_HANDLING_CAPABILITIES_INJECTS_PERSISTENT_POISON);
+}
+
+CXL_EXPORT int cxl_cmd_identify_scans_for_poison(struct cxl_cmd *cmd)
+{
+ cmd_get_field_u8_mask(
+ cmd, identify, IDENTIFY, poison_caps,
+ CXL_CMD_IDENTIFY_POISON_HANDLING_CAPABILITIES_SCANS_FOR_POISON);
+}
+
+CXL_EXPORT int cxl_cmd_identify_egress_port_congestion(struct cxl_cmd *cmd)
+{
+ cmd_get_field_u8_mask(
+ cmd, identify, IDENTIFY, qos_telemetry_caps,
+ CXL_CMD_IDENTIFY_QOS_TELEMETRY_CAPABILITIES_EGRESS_PORT_CONGESTION);
+}
+
+CXL_EXPORT int
+cxl_cmd_identify_temporary_throughput_reduction(struct cxl_cmd *cmd)
+{
+ cmd_get_field_u8_mask(
+ cmd, identify, IDENTIFY, qos_telemetry_caps,
+ CXL_CMD_IDENTIFY_QOS_TELEMETRY_CAPABILITIES_TEMPORARY_THROUGHPUT_REDUCTION);
+}
+
CXL_EXPORT struct cxl_cmd *cxl_cmd_new_raw(struct cxl_memdev *memdev,
int opcode)
{
@@ -249,3 +249,14 @@ global:
cxl_decoder_create_ram_region;
cxl_region_get_daxctl_region;
} LIBCXL_4;
+
+LIBCXL_6 {
+global:
+ cxl_cmd_identify_get_event_log_size;
+ cxl_cmd_identify_get_poison_list_max;
+ cxl_cmd_identify_get_inject_poison_limit;
+ cxl_cmd_identify_injects_persistent_poison;
+ cxl_cmd_identify_scans_for_poison;
+ cxl_cmd_identify_egress_port_congestion;
+ cxl_cmd_identify_temporary_throughput_reduction;
+} LIBCXL_5;
@@ -211,6 +211,17 @@ struct cxl_cmd_identify {
u8 qos_telemetry_caps;
} __attribute__((packed));
+/* CXL 3.0 8.2.9.8.1.1 Identify Memory Device Poison Handling Capabilities */
+#define CXL_CMD_IDENTIFY_POISON_HANDLING_CAPABILITIES_INJECTS_PERSISTENT_POISON \
+ BIT(0)
+#define CXL_CMD_IDENTIFY_POISON_HANDLING_CAPABILITIES_SCANS_FOR_POISON BIT(1)
+
+/* CXL 3.0 8.2.9.8.1.1 Identify Memory Device QoS Telemetry Capabilities */
+#define CXL_CMD_IDENTIFY_QOS_TELEMETRY_CAPABILITIES_EGRESS_PORT_CONGESTION \
+ BIT(0)
+#define CXL_CMD_IDENTIFY_QOS_TELEMETRY_CAPABILITIES_TEMPORARY_THROUGHPUT_REDUCTION \
+ BIT(1)
+
struct cxl_cmd_get_lsa_in {
le32 offset;
le32 length;
@@ -334,6 +334,22 @@ unsigned long long cxl_cmd_identify_get_volatile_only_size(struct cxl_cmd *cmd);
unsigned long long cxl_cmd_identify_get_persistent_only_size(struct cxl_cmd *cmd);
unsigned long long cxl_cmd_identify_get_partition_align(struct cxl_cmd *cmd);
unsigned int cxl_cmd_identify_get_label_size(struct cxl_cmd *cmd);
+
+enum cxl_identify_event {
+ CXL_IDENTIFY_INFO,
+ CXL_IDENTIFY_WARN,
+ CXL_IDENTIFY_FAIL,
+ CXL_IDENTIFY_FATAL,
+};
+
+int cxl_cmd_identify_get_event_log_size(struct cxl_cmd *cmd,
+ enum cxl_identify_event event);
+int cxl_cmd_identify_get_poison_list_max(struct cxl_cmd *cmd);
+int cxl_cmd_identify_get_inject_poison_limit(struct cxl_cmd *cmd);
+int cxl_cmd_identify_injects_persistent_poison(struct cxl_cmd *cmd);
+int cxl_cmd_identify_scans_for_poison(struct cxl_cmd *cmd);
+int cxl_cmd_identify_egress_port_congestion(struct cxl_cmd *cmd);
+int cxl_cmd_identify_temporary_throughput_reduction(struct cxl_cmd *cmd);
struct cxl_cmd *cxl_cmd_new_get_health_info(struct cxl_memdev *memdev);
int cxl_cmd_health_info_get_maintenance_needed(struct cxl_cmd *cmd);
int cxl_cmd_health_info_get_performance_degraded(struct cxl_cmd *cmd);