Commit 077ee5f7 authored by Shiju Jose's avatar Shiju Jose Committed by Dave Jiang
Browse files

cxl/edac: Add support for PERFORM_MAINTENANCE command



Add support for PERFORM_MAINTENANCE command.

CXL spec 3.2 section 8.2.10.7.1 describes the Perform Maintenance command.
This command requests the device to execute the maintenance operation
specified by the maintenance operation class and the maintenance operation
subclass.

Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
Signed-off-by: default avatarShiju Jose <shiju.jose@huawei.com>
Reviewed-by: default avatarAlison Schofield <alison.schofield@intel.com>
Acked-by: default avatarDan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20250521124749.817-6-shiju.jose@huawei.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 85fb6a16
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -813,6 +813,55 @@ static int cxl_memdev_ecs_init(struct cxl_memdev *cxlmd,
	return 0;
}

/*
 * Perform Maintenance CXL 3.2 Spec 8.2.10.7.1
 */

/*
 * Perform Maintenance input payload
 * CXL rev 3.2 section 8.2.10.7.1 Table 8-117
 */
struct cxl_mbox_maintenance_hdr {
	u8 op_class;
	u8 op_subclass;
} __packed;

static int cxl_perform_maintenance(struct cxl_mailbox *cxl_mbox, u8 class,
				   u8 subclass, void *data_in,
				   size_t data_in_size)
{
	struct cxl_memdev_maintenance_pi {
		struct cxl_mbox_maintenance_hdr hdr;
		u8 data[];
	} __packed;
	struct cxl_mbox_cmd mbox_cmd;
	size_t hdr_size;

	struct cxl_memdev_maintenance_pi *pi __free(kvfree) =
		kvzalloc(cxl_mbox->payload_size, GFP_KERNEL);
	if (!pi)
		return -ENOMEM;

	pi->hdr.op_class = class;
	pi->hdr.op_subclass = subclass;
	hdr_size = sizeof(pi->hdr);
	/*
	 * Check minimum mbox payload size is available for
	 * the maintenance data transfer.
	 */
	if (hdr_size + data_in_size > cxl_mbox->payload_size)
		return -ENOMEM;

	memcpy(pi->data, data_in, data_in_size);
	mbox_cmd = (struct cxl_mbox_cmd){
		.opcode = CXL_MBOX_OP_DO_MAINTENANCE,
		.size_in = hdr_size + data_in_size,
		.payload_in = pi,
	};

	return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
}

int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd)
{
	struct edac_dev_feature ras_features[CXL_NR_EDAC_DEV_FEATURES];
+1 −0
Original line number Diff line number Diff line
@@ -531,6 +531,7 @@ enum cxl_opcode {
	CXL_MBOX_OP_GET_SUPPORTED_FEATURES	= 0x0500,
	CXL_MBOX_OP_GET_FEATURE		= 0x0501,
	CXL_MBOX_OP_SET_FEATURE		= 0x0502,
	CXL_MBOX_OP_DO_MAINTENANCE	= 0x0600,
	CXL_MBOX_OP_IDENTIFY		= 0x4000,
	CXL_MBOX_OP_GET_PARTITION_INFO	= 0x4100,
	CXL_MBOX_OP_SET_PARTITION_INFO	= 0x4101,