876 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* Copyright(c) 2020-2021 Intel Corporation. */3#ifndef __CXL_MEM_H__4#define __CXL_MEM_H__5#include <uapi/linux/cxl_mem.h>6#include <linux/pci.h>7#include <linux/cdev.h>8#include <linux/uuid.h>9#include <linux/node.h>10#include <cxl/event.h>11#include <cxl/mailbox.h>12#include "cxl.h"13 14/* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */15#define CXLMDEV_STATUS_OFFSET 0x016#define CXLMDEV_DEV_FATAL BIT(0)17#define CXLMDEV_FW_HALT BIT(1)18#define CXLMDEV_STATUS_MEDIA_STATUS_MASK GENMASK(3, 2)19#define CXLMDEV_MS_NOT_READY 020#define CXLMDEV_MS_READY 121#define CXLMDEV_MS_ERROR 222#define CXLMDEV_MS_DISABLED 323#define CXLMDEV_READY(status) \24 (FIELD_GET(CXLMDEV_STATUS_MEDIA_STATUS_MASK, status) == \25 CXLMDEV_MS_READY)26#define CXLMDEV_MBOX_IF_READY BIT(4)27#define CXLMDEV_RESET_NEEDED_MASK GENMASK(7, 5)28#define CXLMDEV_RESET_NEEDED_NOT 029#define CXLMDEV_RESET_NEEDED_COLD 130#define CXLMDEV_RESET_NEEDED_WARM 231#define CXLMDEV_RESET_NEEDED_HOT 332#define CXLMDEV_RESET_NEEDED_CXL 433#define CXLMDEV_RESET_NEEDED(status) \34 (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \35 CXLMDEV_RESET_NEEDED_NOT)36 37/**38 * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device39 * @dev: driver core device object40 * @cdev: char dev core object for ioctl operations41 * @cxlds: The device state backing this device42 * @detach_work: active memdev lost a port in its ancestry43 * @cxl_nvb: coordinate removal of @cxl_nvd if present44 * @cxl_nvd: optional bridge to an nvdimm if the device supports pmem45 * @endpoint: connection to the CXL port topology for this memory device46 * @id: id number of this memdev instance.47 * @depth: endpoint port depth48 */49struct cxl_memdev {50 struct device dev;51 struct cdev cdev;52 struct cxl_dev_state *cxlds;53 struct work_struct detach_work;54 struct cxl_nvdimm_bridge *cxl_nvb;55 struct cxl_nvdimm *cxl_nvd;56 struct cxl_port *endpoint;57 int id;58 int depth;59};60 61static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)62{63 return container_of(dev, struct cxl_memdev, dev);64}65 66static inline struct cxl_port *cxled_to_port(struct cxl_endpoint_decoder *cxled)67{68 return to_cxl_port(cxled->cxld.dev.parent);69}70 71static inline struct cxl_port *cxlrd_to_port(struct cxl_root_decoder *cxlrd)72{73 return to_cxl_port(cxlrd->cxlsd.cxld.dev.parent);74}75 76static inline struct cxl_memdev *77cxled_to_memdev(struct cxl_endpoint_decoder *cxled)78{79 struct cxl_port *port = to_cxl_port(cxled->cxld.dev.parent);80 81 return to_cxl_memdev(port->uport_dev);82}83 84bool is_cxl_memdev(const struct device *dev);85static inline bool is_cxl_endpoint(struct cxl_port *port)86{87 return is_cxl_memdev(port->uport_dev);88}89 90struct cxl_memdev *devm_cxl_add_memdev(struct device *host,91 struct cxl_dev_state *cxlds);92int devm_cxl_sanitize_setup_notifier(struct device *host,93 struct cxl_memdev *cxlmd);94struct cxl_memdev_state;95int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds);96int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,97 resource_size_t base, resource_size_t len,98 resource_size_t skipped);99 100static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,101 struct cxl_memdev *cxlmd)102{103 if (!port)104 return NULL;105 106 return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev);107}108 109/**110 * struct cxl_mbox_cmd - A command to be submitted to hardware.111 * @opcode: (input) The command set and command submitted to hardware.112 * @payload_in: (input) Pointer to the input payload.113 * @payload_out: (output) Pointer to the output payload. Must be allocated by114 * the caller.115 * @size_in: (input) Number of bytes to load from @payload_in.116 * @size_out: (input) Max number of bytes loaded into @payload_out.117 * (output) Number of bytes generated by the device. For fixed size118 * outputs commands this is always expected to be deterministic. For119 * variable sized output commands, it tells the exact number of bytes120 * written.121 * @min_out: (input) internal command output payload size validation122 * @poll_count: (input) Number of timeouts to attempt.123 * @poll_interval_ms: (input) Time between mailbox background command polling124 * interval timeouts.125 * @return_code: (output) Error code returned from hardware.126 *127 * This is the primary mechanism used to send commands to the hardware.128 * All the fields except @payload_* correspond exactly to the fields described in129 * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and130 * @payload_out are written to, and read from the Command Payload Registers131 * defined in CXL 2.0 8.2.8.4.8.132 */133struct cxl_mbox_cmd {134 u16 opcode;135 void *payload_in;136 void *payload_out;137 size_t size_in;138 size_t size_out;139 size_t min_out;140 int poll_count;141 int poll_interval_ms;142 u16 return_code;143};144 145/*146 * Per CXL 3.0 Section 8.2.8.4.5.1147 */148#define CMD_CMD_RC_TABLE \149 C(SUCCESS, 0, NULL), \150 C(BACKGROUND, -ENXIO, "background cmd started successfully"), \151 C(INPUT, -ENXIO, "cmd input was invalid"), \152 C(UNSUPPORTED, -ENXIO, "cmd is not supported"), \153 C(INTERNAL, -ENXIO, "internal device error"), \154 C(RETRY, -ENXIO, "temporary error, retry once"), \155 C(BUSY, -ENXIO, "ongoing background operation"), \156 C(MEDIADISABLED, -ENXIO, "media access is disabled"), \157 C(FWINPROGRESS, -ENXIO, "one FW package can be transferred at a time"), \158 C(FWOOO, -ENXIO, "FW package content was transferred out of order"), \159 C(FWAUTH, -ENXIO, "FW package authentication failed"), \160 C(FWSLOT, -ENXIO, "FW slot is not supported for requested operation"), \161 C(FWROLLBACK, -ENXIO, "rolled back to the previous active FW"), \162 C(FWRESET, -ENXIO, "FW failed to activate, needs cold reset"), \163 C(HANDLE, -ENXIO, "one or more Event Record Handles were invalid"), \164 C(PADDR, -EFAULT, "physical address specified is invalid"), \165 C(POISONLMT, -EBUSY, "poison injection limit has been reached"), \166 C(MEDIAFAILURE, -ENXIO, "permanent issue with the media"), \167 C(ABORT, -ENXIO, "background cmd was aborted by device"), \168 C(SECURITY, -ENXIO, "not valid in the current security state"), \169 C(PASSPHRASE, -ENXIO, "phrase doesn't match current set passphrase"), \170 C(MBUNSUPPORTED, -ENXIO, "unsupported on the mailbox it was issued on"),\171 C(PAYLOADLEN, -ENXIO, "invalid payload length"), \172 C(LOG, -ENXIO, "invalid or unsupported log page"), \173 C(INTERRUPTED, -ENXIO, "asynchronous event occured"), \174 C(FEATUREVERSION, -ENXIO, "unsupported feature version"), \175 C(FEATURESELVALUE, -ENXIO, "unsupported feature selection value"), \176 C(FEATURETRANSFERIP, -ENXIO, "feature transfer in progress"), \177 C(FEATURETRANSFEROOO, -ENXIO, "feature transfer out of order"), \178 C(RESOURCEEXHAUSTED, -ENXIO, "resources are exhausted"), \179 C(EXTLIST, -ENXIO, "invalid Extent List"), \180 181#undef C182#define C(a, b, c) CXL_MBOX_CMD_RC_##a183enum { CMD_CMD_RC_TABLE };184#undef C185#define C(a, b, c) { b, c }186struct cxl_mbox_cmd_rc {187 int err;188 const char *desc;189};190 191static const192struct cxl_mbox_cmd_rc cxl_mbox_cmd_rctable[] ={ CMD_CMD_RC_TABLE };193#undef C194 195static inline const char *cxl_mbox_cmd_rc2str(struct cxl_mbox_cmd *mbox_cmd)196{197 return cxl_mbox_cmd_rctable[mbox_cmd->return_code].desc;198}199 200static inline int cxl_mbox_cmd_rc2errno(struct cxl_mbox_cmd *mbox_cmd)201{202 return cxl_mbox_cmd_rctable[mbox_cmd->return_code].err;203}204 205/*206 * CXL 2.0 - Memory capacity multiplier207 * See Section 8.2.9.5208 *209 * Volatile, Persistent, and Partition capacities are specified to be in210 * multiples of 256MB - define a multiplier to convert to/from bytes.211 */212#define CXL_CAPACITY_MULTIPLIER SZ_256M213 214/*215 * Event Interrupt Policy216 *217 * CXL rev 3.0 section 8.2.9.2.4; Table 8-52218 */219enum cxl_event_int_mode {220 CXL_INT_NONE = 0x00,221 CXL_INT_MSI_MSIX = 0x01,222 CXL_INT_FW = 0x02223};224struct cxl_event_interrupt_policy {225 u8 info_settings;226 u8 warn_settings;227 u8 failure_settings;228 u8 fatal_settings;229} __packed;230 231/**232 * struct cxl_event_state - Event log driver state233 *234 * @buf: Buffer to receive event data235 * @log_lock: Serialize event_buf and log use236 */237struct cxl_event_state {238 struct cxl_get_event_payload *buf;239 struct mutex log_lock;240};241 242/* Device enabled poison commands */243enum poison_cmd_enabled_bits {244 CXL_POISON_ENABLED_LIST,245 CXL_POISON_ENABLED_INJECT,246 CXL_POISON_ENABLED_CLEAR,247 CXL_POISON_ENABLED_SCAN_CAPS,248 CXL_POISON_ENABLED_SCAN_MEDIA,249 CXL_POISON_ENABLED_SCAN_RESULTS,250 CXL_POISON_ENABLED_MAX251};252 253/* Device enabled security commands */254enum security_cmd_enabled_bits {255 CXL_SEC_ENABLED_SANITIZE,256 CXL_SEC_ENABLED_SECURE_ERASE,257 CXL_SEC_ENABLED_GET_SECURITY_STATE,258 CXL_SEC_ENABLED_SET_PASSPHRASE,259 CXL_SEC_ENABLED_DISABLE_PASSPHRASE,260 CXL_SEC_ENABLED_UNLOCK,261 CXL_SEC_ENABLED_FREEZE_SECURITY,262 CXL_SEC_ENABLED_PASSPHRASE_SECURE_ERASE,263 CXL_SEC_ENABLED_MAX264};265 266/**267 * struct cxl_poison_state - Driver poison state info268 *269 * @max_errors: Maximum media error records held in device cache270 * @enabled_cmds: All poison commands enabled in the CEL271 * @list_out: The poison list payload returned by device272 * @lock: Protect reads of the poison list273 *274 * Reads of the poison list are synchronized to ensure that a reader275 * does not get an incomplete list because their request overlapped276 * (was interrupted or preceded by) another read request of the same277 * DPA range. CXL Spec 3.0 Section 8.2.9.8.4.1278 */279struct cxl_poison_state {280 u32 max_errors;281 DECLARE_BITMAP(enabled_cmds, CXL_POISON_ENABLED_MAX);282 struct cxl_mbox_poison_out *list_out;283 struct mutex lock; /* Protect reads of poison list */284};285 286/*287 * Get FW Info288 * CXL rev 3.0 section 8.2.9.3.1; Table 8-56289 */290struct cxl_mbox_get_fw_info {291 u8 num_slots;292 u8 slot_info;293 u8 activation_cap;294 u8 reserved[13];295 char slot_1_revision[16];296 char slot_2_revision[16];297 char slot_3_revision[16];298 char slot_4_revision[16];299} __packed;300 301#define CXL_FW_INFO_SLOT_INFO_CUR_MASK GENMASK(2, 0)302#define CXL_FW_INFO_SLOT_INFO_NEXT_MASK GENMASK(5, 3)303#define CXL_FW_INFO_SLOT_INFO_NEXT_SHIFT 3304#define CXL_FW_INFO_ACTIVATION_CAP_HAS_LIVE_ACTIVATE BIT(0)305 306/*307 * Transfer FW Input Payload308 * CXL rev 3.0 section 8.2.9.3.2; Table 8-57309 */310struct cxl_mbox_transfer_fw {311 u8 action;312 u8 slot;313 u8 reserved[2];314 __le32 offset;315 u8 reserved2[0x78];316 u8 data[];317} __packed;318 319#define CXL_FW_TRANSFER_ACTION_FULL 0x0320#define CXL_FW_TRANSFER_ACTION_INITIATE 0x1321#define CXL_FW_TRANSFER_ACTION_CONTINUE 0x2322#define CXL_FW_TRANSFER_ACTION_END 0x3323#define CXL_FW_TRANSFER_ACTION_ABORT 0x4324 325/*326 * CXL rev 3.0 section 8.2.9.3.2 mandates 128-byte alignment for FW packages327 * and for each part transferred in a Transfer FW command.328 */329#define CXL_FW_TRANSFER_ALIGNMENT 128330 331/*332 * Activate FW Input Payload333 * CXL rev 3.0 section 8.2.9.3.3; Table 8-58334 */335struct cxl_mbox_activate_fw {336 u8 action;337 u8 slot;338} __packed;339 340#define CXL_FW_ACTIVATE_ONLINE 0x0341#define CXL_FW_ACTIVATE_OFFLINE 0x1342 343/* FW state bits */344#define CXL_FW_STATE_BITS 32345#define CXL_FW_CANCEL 0346 347/**348 * struct cxl_fw_state - Firmware upload / activation state349 *350 * @state: fw_uploader state bitmask351 * @oneshot: whether the fw upload fits in a single transfer352 * @num_slots: Number of FW slots available353 * @cur_slot: Slot number currently active354 * @next_slot: Slot number for the new firmware355 */356struct cxl_fw_state {357 DECLARE_BITMAP(state, CXL_FW_STATE_BITS);358 bool oneshot;359 int num_slots;360 int cur_slot;361 int next_slot;362};363 364/**365 * struct cxl_security_state - Device security state366 *367 * @state: state of last security operation368 * @enabled_cmds: All security commands enabled in the CEL369 * @poll_tmo_secs: polling timeout370 * @sanitize_active: sanitize completion pending371 * @poll_dwork: polling work item372 * @sanitize_node: sanitation sysfs file to notify373 */374struct cxl_security_state {375 unsigned long state;376 DECLARE_BITMAP(enabled_cmds, CXL_SEC_ENABLED_MAX);377 int poll_tmo_secs;378 bool sanitize_active;379 struct delayed_work poll_dwork;380 struct kernfs_node *sanitize_node;381};382 383/*384 * enum cxl_devtype - delineate type-2 from a generic type-3 device385 * @CXL_DEVTYPE_DEVMEM - Vendor specific CXL Type-2 device implementing HDM-D or386 * HDM-DB, no requirement that this device implements a387 * mailbox, or other memory-device-standard manageability388 * flows.389 * @CXL_DEVTYPE_CLASSMEM - Common class definition of a CXL Type-3 device with390 * HDM-H and class-mandatory memory device registers391 */392enum cxl_devtype {393 CXL_DEVTYPE_DEVMEM,394 CXL_DEVTYPE_CLASSMEM,395};396 397/**398 * struct cxl_dpa_perf - DPA performance property entry399 * @dpa_range: range for DPA address400 * @coord: QoS performance data (i.e. latency, bandwidth)401 * @cdat_coord: raw QoS performance data from CDAT402 * @qos_class: QoS Class cookies403 */404struct cxl_dpa_perf {405 struct range dpa_range;406 struct access_coordinate coord[ACCESS_COORDINATE_MAX];407 struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];408 int qos_class;409};410 411/**412 * struct cxl_dev_state - The driver device state413 *414 * cxl_dev_state represents the CXL driver/device state. It provides an415 * interface to mailbox commands as well as some cached data about the device.416 * Currently only memory devices are represented.417 *418 * @dev: The device associated with this CXL state419 * @cxlmd: The device representing the CXL.mem capabilities of @dev420 * @reg_map: component and ras register mapping parameters421 * @regs: Parsed register blocks422 * @cxl_dvsec: Offset to the PCIe device DVSEC423 * @rcd: operating in RCD mode (CXL 3.0 9.11.8 CXL Devices Attached to an RCH)424 * @media_ready: Indicate whether the device media is usable425 * @dpa_res: Overall DPA resource tree for the device426 * @pmem_res: Active Persistent memory capacity configuration427 * @ram_res: Active Volatile memory capacity configuration428 * @serial: PCIe Device Serial Number429 * @type: Generic Memory Class device or Vendor Specific Memory device430 * @cxl_mbox: CXL mailbox context431 */432struct cxl_dev_state {433 struct device *dev;434 struct cxl_memdev *cxlmd;435 struct cxl_register_map reg_map;436 struct cxl_regs regs;437 int cxl_dvsec;438 bool rcd;439 bool media_ready;440 struct resource dpa_res;441 struct resource pmem_res;442 struct resource ram_res;443 u64 serial;444 enum cxl_devtype type;445 struct cxl_mailbox cxl_mbox;446};447 448static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)449{450 return dev_get_drvdata(cxl_mbox->host);451}452 453/**454 * struct cxl_memdev_state - Generic Type-3 Memory Device Class driver data455 *456 * CXL 8.1.12.1 PCI Header - Class Code Register Memory Device defines457 * common memory device functionality like the presence of a mailbox and458 * the functionality related to that like Identify Memory Device and Get459 * Partition Info460 * @cxlds: Core driver state common across Type-2 and Type-3 devices461 * @lsa_size: Size of Label Storage Area462 * (CXL 2.0 8.2.9.5.1.1 Identify Memory Device)463 * @firmware_version: Firmware version for the memory device.464 * @enabled_cmds: Hardware commands found enabled in CEL.465 * @exclusive_cmds: Commands that are kernel-internal only466 * @total_bytes: sum of all possible capacities467 * @volatile_only_bytes: hard volatile capacity468 * @persistent_only_bytes: hard persistent capacity469 * @partition_align_bytes: alignment size for partition-able capacity470 * @active_volatile_bytes: sum of hard + soft volatile471 * @active_persistent_bytes: sum of hard + soft persistent472 * @next_volatile_bytes: volatile capacity change pending device reset473 * @next_persistent_bytes: persistent capacity change pending device reset474 * @ram_perf: performance data entry matched to RAM partition475 * @pmem_perf: performance data entry matched to PMEM partition476 * @event: event log driver state477 * @poison: poison driver state info478 * @security: security driver state info479 * @fw: firmware upload / activation state480 *481 * See CXL 3.0 8.2.9.8.2 Capacity Configuration and Label Storage for482 * details on capacity parameters.483 */484struct cxl_memdev_state {485 struct cxl_dev_state cxlds;486 size_t lsa_size;487 char firmware_version[0x10];488 DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX);489 DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);490 u64 total_bytes;491 u64 volatile_only_bytes;492 u64 persistent_only_bytes;493 u64 partition_align_bytes;494 u64 active_volatile_bytes;495 u64 active_persistent_bytes;496 u64 next_volatile_bytes;497 u64 next_persistent_bytes;498 499 struct cxl_dpa_perf ram_perf;500 struct cxl_dpa_perf pmem_perf;501 502 struct cxl_event_state event;503 struct cxl_poison_state poison;504 struct cxl_security_state security;505 struct cxl_fw_state fw;506};507 508static inline struct cxl_memdev_state *509to_cxl_memdev_state(struct cxl_dev_state *cxlds)510{511 if (cxlds->type != CXL_DEVTYPE_CLASSMEM)512 return NULL;513 return container_of(cxlds, struct cxl_memdev_state, cxlds);514}515 516enum cxl_opcode {517 CXL_MBOX_OP_INVALID = 0x0000,518 CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID,519 CXL_MBOX_OP_GET_EVENT_RECORD = 0x0100,520 CXL_MBOX_OP_CLEAR_EVENT_RECORD = 0x0101,521 CXL_MBOX_OP_GET_EVT_INT_POLICY = 0x0102,522 CXL_MBOX_OP_SET_EVT_INT_POLICY = 0x0103,523 CXL_MBOX_OP_GET_FW_INFO = 0x0200,524 CXL_MBOX_OP_TRANSFER_FW = 0x0201,525 CXL_MBOX_OP_ACTIVATE_FW = 0x0202,526 CXL_MBOX_OP_GET_TIMESTAMP = 0x0300,527 CXL_MBOX_OP_SET_TIMESTAMP = 0x0301,528 CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400,529 CXL_MBOX_OP_GET_LOG = 0x0401,530 CXL_MBOX_OP_GET_LOG_CAPS = 0x0402,531 CXL_MBOX_OP_CLEAR_LOG = 0x0403,532 CXL_MBOX_OP_GET_SUP_LOG_SUBLIST = 0x0405,533 CXL_MBOX_OP_IDENTIFY = 0x4000,534 CXL_MBOX_OP_GET_PARTITION_INFO = 0x4100,535 CXL_MBOX_OP_SET_PARTITION_INFO = 0x4101,536 CXL_MBOX_OP_GET_LSA = 0x4102,537 CXL_MBOX_OP_SET_LSA = 0x4103,538 CXL_MBOX_OP_GET_HEALTH_INFO = 0x4200,539 CXL_MBOX_OP_GET_ALERT_CONFIG = 0x4201,540 CXL_MBOX_OP_SET_ALERT_CONFIG = 0x4202,541 CXL_MBOX_OP_GET_SHUTDOWN_STATE = 0x4203,542 CXL_MBOX_OP_SET_SHUTDOWN_STATE = 0x4204,543 CXL_MBOX_OP_GET_POISON = 0x4300,544 CXL_MBOX_OP_INJECT_POISON = 0x4301,545 CXL_MBOX_OP_CLEAR_POISON = 0x4302,546 CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303,547 CXL_MBOX_OP_SCAN_MEDIA = 0x4304,548 CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305,549 CXL_MBOX_OP_SANITIZE = 0x4400,550 CXL_MBOX_OP_SECURE_ERASE = 0x4401,551 CXL_MBOX_OP_GET_SECURITY_STATE = 0x4500,552 CXL_MBOX_OP_SET_PASSPHRASE = 0x4501,553 CXL_MBOX_OP_DISABLE_PASSPHRASE = 0x4502,554 CXL_MBOX_OP_UNLOCK = 0x4503,555 CXL_MBOX_OP_FREEZE_SECURITY = 0x4504,556 CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE = 0x4505,557 CXL_MBOX_OP_MAX = 0x10000558};559 560#define DEFINE_CXL_CEL_UUID \561 UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96, 0xb1, 0x62, \562 0x3b, 0x3f, 0x17)563 564#define DEFINE_CXL_VENDOR_DEBUG_UUID \565 UUID_INIT(0x5e1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6, 0x07, 0x19, \566 0x40, 0x3d, 0x86)567 568struct cxl_mbox_get_supported_logs {569 __le16 entries;570 u8 rsvd[6];571 struct cxl_gsl_entry {572 uuid_t uuid;573 __le32 size;574 } __packed entry[];575} __packed;576 577struct cxl_cel_entry {578 __le16 opcode;579 __le16 effect;580} __packed;581 582struct cxl_mbox_get_log {583 uuid_t uuid;584 __le32 offset;585 __le32 length;586} __packed;587 588/* See CXL 2.0 Table 175 Identify Memory Device Output Payload */589struct cxl_mbox_identify {590 char fw_revision[0x10];591 __le64 total_capacity;592 __le64 volatile_capacity;593 __le64 persistent_capacity;594 __le64 partition_align;595 __le16 info_event_log_size;596 __le16 warning_event_log_size;597 __le16 failure_event_log_size;598 __le16 fatal_event_log_size;599 __le32 lsa_size;600 u8 poison_list_max_mer[3];601 __le16 inject_poison_limit;602 u8 poison_caps;603 u8 qos_telemetry_caps;604} __packed;605 606/*607 * General Media Event Record UUID608 * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43609 */610#define CXL_EVENT_GEN_MEDIA_UUID \611 UUID_INIT(0xfbcd0a77, 0xc260, 0x417f, 0x85, 0xa9, 0x08, 0x8b, 0x16, \612 0x21, 0xeb, 0xa6)613 614/*615 * DRAM Event Record UUID616 * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44617 */618#define CXL_EVENT_DRAM_UUID \619 UUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, \620 0x5c, 0x96, 0x24)621 622/*623 * Memory Module Event Record UUID624 * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45625 */626#define CXL_EVENT_MEM_MODULE_UUID \627 UUID_INIT(0xfe927475, 0xdd59, 0x4339, 0xa5, 0x86, 0x79, 0xba, 0xb1, \628 0x13, 0xb7, 0x74)629 630/*631 * Get Event Records output payload632 * CXL rev 3.0 section 8.2.9.2.2; Table 8-50633 */634#define CXL_GET_EVENT_FLAG_OVERFLOW BIT(0)635#define CXL_GET_EVENT_FLAG_MORE_RECORDS BIT(1)636struct cxl_get_event_payload {637 u8 flags;638 u8 reserved1;639 __le16 overflow_err_count;640 __le64 first_overflow_timestamp;641 __le64 last_overflow_timestamp;642 __le16 record_count;643 u8 reserved2[10];644 struct cxl_event_record_raw records[];645} __packed;646 647/*648 * CXL rev 3.0 section 8.2.9.2.2; Table 8-49649 */650enum cxl_event_log_type {651 CXL_EVENT_TYPE_INFO = 0x00,652 CXL_EVENT_TYPE_WARN,653 CXL_EVENT_TYPE_FAIL,654 CXL_EVENT_TYPE_FATAL,655 CXL_EVENT_TYPE_MAX656};657 658/*659 * Clear Event Records input payload660 * CXL rev 3.0 section 8.2.9.2.3; Table 8-51661 */662struct cxl_mbox_clear_event_payload {663 u8 event_log; /* enum cxl_event_log_type */664 u8 clear_flags;665 u8 nr_recs;666 u8 reserved[3];667 __le16 handles[];668} __packed;669#define CXL_CLEAR_EVENT_MAX_HANDLES U8_MAX670 671struct cxl_mbox_get_partition_info {672 __le64 active_volatile_cap;673 __le64 active_persistent_cap;674 __le64 next_volatile_cap;675 __le64 next_persistent_cap;676} __packed;677 678struct cxl_mbox_get_lsa {679 __le32 offset;680 __le32 length;681} __packed;682 683struct cxl_mbox_set_lsa {684 __le32 offset;685 __le32 reserved;686 u8 data[];687} __packed;688 689struct cxl_mbox_set_partition_info {690 __le64 volatile_capacity;691 u8 flags;692} __packed;693 694#define CXL_SET_PARTITION_IMMEDIATE_FLAG BIT(0)695 696/* Set Timestamp CXL 3.0 Spec 8.2.9.4.2 */697struct cxl_mbox_set_timestamp_in {698 __le64 timestamp;699 700} __packed;701 702/* Get Poison List CXL 3.0 Spec 8.2.9.8.4.1 */703struct cxl_mbox_poison_in {704 __le64 offset;705 __le64 length;706} __packed;707 708struct cxl_mbox_poison_out {709 u8 flags;710 u8 rsvd1;711 __le64 overflow_ts;712 __le16 count;713 u8 rsvd2[20];714 struct cxl_poison_record {715 __le64 address;716 __le32 length;717 __le32 rsvd;718 } __packed record[];719} __packed;720 721/*722 * Get Poison List address field encodes the starting723 * address of poison, and the source of the poison.724 */725#define CXL_POISON_START_MASK GENMASK_ULL(63, 6)726#define CXL_POISON_SOURCE_MASK GENMASK(2, 0)727 728/* Get Poison List record length is in units of 64 bytes */729#define CXL_POISON_LEN_MULT 64730 731/* Kernel defined maximum for a list of poison errors */732#define CXL_POISON_LIST_MAX 1024733 734/* Get Poison List: Payload out flags */735#define CXL_POISON_FLAG_MORE BIT(0)736#define CXL_POISON_FLAG_OVERFLOW BIT(1)737#define CXL_POISON_FLAG_SCANNING BIT(2)738 739/* Get Poison List: Poison Source */740#define CXL_POISON_SOURCE_UNKNOWN 0741#define CXL_POISON_SOURCE_EXTERNAL 1742#define CXL_POISON_SOURCE_INTERNAL 2743#define CXL_POISON_SOURCE_INJECTED 3744#define CXL_POISON_SOURCE_VENDOR 7745 746/* Inject & Clear Poison CXL 3.0 Spec 8.2.9.8.4.2/3 */747struct cxl_mbox_inject_poison {748 __le64 address;749};750 751/* Clear Poison CXL 3.0 Spec 8.2.9.8.4.3 */752struct cxl_mbox_clear_poison {753 __le64 address;754 u8 write_data[CXL_POISON_LEN_MULT];755} __packed;756 757/**758 * struct cxl_mem_command - Driver representation of a memory device command759 * @info: Command information as it exists for the UAPI760 * @opcode: The actual bits used for the mailbox protocol761 * @flags: Set of flags effecting driver behavior.762 *763 * * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag764 * will be enabled by the driver regardless of what hardware may have765 * advertised.766 *767 * The cxl_mem_command is the driver's internal representation of commands that768 * are supported by the driver. Some of these commands may not be supported by769 * the hardware. The driver will use @info to validate the fields passed in by770 * the user then submit the @opcode to the hardware.771 *772 * See struct cxl_command_info.773 */774struct cxl_mem_command {775 struct cxl_command_info info;776 enum cxl_opcode opcode;777 u32 flags;778#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)779};780 781#define CXL_PMEM_SEC_STATE_USER_PASS_SET 0x01782#define CXL_PMEM_SEC_STATE_MASTER_PASS_SET 0x02783#define CXL_PMEM_SEC_STATE_LOCKED 0x04784#define CXL_PMEM_SEC_STATE_FROZEN 0x08785#define CXL_PMEM_SEC_STATE_USER_PLIMIT 0x10786#define CXL_PMEM_SEC_STATE_MASTER_PLIMIT 0x20787 788/* set passphrase input payload */789struct cxl_set_pass {790 u8 type;791 u8 reserved[31];792 /* CXL field using NVDIMM define, same length */793 u8 old_pass[NVDIMM_PASSPHRASE_LEN];794 u8 new_pass[NVDIMM_PASSPHRASE_LEN];795} __packed;796 797/* disable passphrase input payload */798struct cxl_disable_pass {799 u8 type;800 u8 reserved[31];801 u8 pass[NVDIMM_PASSPHRASE_LEN];802} __packed;803 804/* passphrase secure erase payload */805struct cxl_pass_erase {806 u8 type;807 u8 reserved[31];808 u8 pass[NVDIMM_PASSPHRASE_LEN];809} __packed;810 811enum {812 CXL_PMEM_SEC_PASS_MASTER = 0,813 CXL_PMEM_SEC_PASS_USER,814};815 816int cxl_internal_send_cmd(struct cxl_mailbox *cxl_mbox,817 struct cxl_mbox_cmd *cmd);818int cxl_dev_state_identify(struct cxl_memdev_state *mds);819int cxl_await_media_ready(struct cxl_dev_state *cxlds);820int cxl_enumerate_cmds(struct cxl_memdev_state *mds);821int cxl_mem_create_range_info(struct cxl_memdev_state *mds);822struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev);823void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,824 unsigned long *cmds);825void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,826 unsigned long *cmds);827void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status);828void cxl_event_trace_record(const struct cxl_memdev *cxlmd,829 enum cxl_event_log_type type,830 enum cxl_event_type event_type,831 const uuid_t *uuid, union cxl_event *evt);832int cxl_set_timestamp(struct cxl_memdev_state *mds);833int cxl_poison_state_init(struct cxl_memdev_state *mds);834int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,835 struct cxl_region *cxlr);836int cxl_trigger_poison_list(struct cxl_memdev *cxlmd);837int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa);838int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa);839 840#ifdef CONFIG_CXL_SUSPEND841void cxl_mem_active_inc(void);842void cxl_mem_active_dec(void);843#else844static inline void cxl_mem_active_inc(void)845{846}847static inline void cxl_mem_active_dec(void)848{849}850#endif851 852int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd);853 854/**855 * struct cxl_hdm - HDM Decoder registers and cached / decoded capabilities856 * @regs: mapped registers, see devm_cxl_setup_hdm()857 * @decoder_count: number of decoders for this port858 * @target_count: for switch decoders, max downstream port targets859 * @interleave_mask: interleave granularity capability, see check_interleave_cap()860 * @iw_cap_mask: bitmask of supported interleave ways, see check_interleave_cap()861 * @port: mapped cxl_port, see devm_cxl_setup_hdm()862 */863struct cxl_hdm {864 struct cxl_component_regs regs;865 unsigned int decoder_count;866 unsigned int target_count;867 unsigned int interleave_mask;868 unsigned long iw_cap_mask;869 struct cxl_port *port;870};871 872struct seq_file;873struct dentry *cxl_debugfs_create_dir(const char *dir);874void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);875#endif /* __CXL_MEM_H__ */876