0001
0002
0003 #ifndef __CXL_MEM_H__
0004 #define __CXL_MEM_H__
0005 #include <uapi/linux/cxl_mem.h>
0006 #include <linux/cdev.h>
0007 #include "cxl.h"
0008
0009
0010 #define CXLMDEV_STATUS_OFFSET 0x0
0011 #define CXLMDEV_DEV_FATAL BIT(0)
0012 #define CXLMDEV_FW_HALT BIT(1)
0013 #define CXLMDEV_STATUS_MEDIA_STATUS_MASK GENMASK(3, 2)
0014 #define CXLMDEV_MS_NOT_READY 0
0015 #define CXLMDEV_MS_READY 1
0016 #define CXLMDEV_MS_ERROR 2
0017 #define CXLMDEV_MS_DISABLED 3
0018 #define CXLMDEV_READY(status) \
0019 (FIELD_GET(CXLMDEV_STATUS_MEDIA_STATUS_MASK, status) == \
0020 CXLMDEV_MS_READY)
0021 #define CXLMDEV_MBOX_IF_READY BIT(4)
0022 #define CXLMDEV_RESET_NEEDED_MASK GENMASK(7, 5)
0023 #define CXLMDEV_RESET_NEEDED_NOT 0
0024 #define CXLMDEV_RESET_NEEDED_COLD 1
0025 #define CXLMDEV_RESET_NEEDED_WARM 2
0026 #define CXLMDEV_RESET_NEEDED_HOT 3
0027 #define CXLMDEV_RESET_NEEDED_CXL 4
0028 #define CXLMDEV_RESET_NEEDED(status) \
0029 (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \
0030 CXLMDEV_RESET_NEEDED_NOT)
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 struct cxl_memdev {
0041 struct device dev;
0042 struct cdev cdev;
0043 struct cxl_dev_state *cxlds;
0044 struct work_struct detach_work;
0045 int id;
0046 };
0047
0048 static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
0049 {
0050 return container_of(dev, struct cxl_memdev, dev);
0051 }
0052
0053 static inline struct cxl_port *cxled_to_port(struct cxl_endpoint_decoder *cxled)
0054 {
0055 return to_cxl_port(cxled->cxld.dev.parent);
0056 }
0057
0058 static inline struct cxl_port *cxlrd_to_port(struct cxl_root_decoder *cxlrd)
0059 {
0060 return to_cxl_port(cxlrd->cxlsd.cxld.dev.parent);
0061 }
0062
0063 static inline struct cxl_memdev *
0064 cxled_to_memdev(struct cxl_endpoint_decoder *cxled)
0065 {
0066 struct cxl_port *port = to_cxl_port(cxled->cxld.dev.parent);
0067
0068 return to_cxl_memdev(port->uport);
0069 }
0070
0071 bool is_cxl_memdev(struct device *dev);
0072 static inline bool is_cxl_endpoint(struct cxl_port *port)
0073 {
0074 return is_cxl_memdev(port->uport);
0075 }
0076
0077 struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds);
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 struct cxl_mbox_cmd {
0100 u16 opcode;
0101 void *payload_in;
0102 void *payload_out;
0103 size_t size_in;
0104 size_t size_out;
0105 u16 return_code;
0106 };
0107
0108
0109
0110
0111 #define CMD_CMD_RC_TABLE \
0112 C(SUCCESS, 0, NULL), \
0113 C(BACKGROUND, -ENXIO, "background cmd started successfully"), \
0114 C(INPUT, -ENXIO, "cmd input was invalid"), \
0115 C(UNSUPPORTED, -ENXIO, "cmd is not supported"), \
0116 C(INTERNAL, -ENXIO, "internal device error"), \
0117 C(RETRY, -ENXIO, "temporary error, retry once"), \
0118 C(BUSY, -ENXIO, "ongoing background operation"), \
0119 C(MEDIADISABLED, -ENXIO, "media access is disabled"), \
0120 C(FWINPROGRESS, -ENXIO, "one FW package can be transferred at a time"), \
0121 C(FWOOO, -ENXIO, "FW package content was transferred out of order"), \
0122 C(FWAUTH, -ENXIO, "FW package authentication failed"), \
0123 C(FWSLOT, -ENXIO, "FW slot is not supported for requested operation"), \
0124 C(FWROLLBACK, -ENXIO, "rolled back to the previous active FW"), \
0125 C(FWRESET, -ENXIO, "FW failed to activate, needs cold reset"), \
0126 C(HANDLE, -ENXIO, "one or more Event Record Handles were invalid"), \
0127 C(PADDR, -ENXIO, "physical address specified is invalid"), \
0128 C(POISONLMT, -ENXIO, "poison injection limit has been reached"), \
0129 C(MEDIAFAILURE, -ENXIO, "permanent issue with the media"), \
0130 C(ABORT, -ENXIO, "background cmd was aborted by device"), \
0131 C(SECURITY, -ENXIO, "not valid in the current security state"), \
0132 C(PASSPHRASE, -ENXIO, "phrase doesn't match current set passphrase"), \
0133 C(MBUNSUPPORTED, -ENXIO, "unsupported on the mailbox it was issued on"),\
0134 C(PAYLOADLEN, -ENXIO, "invalid payload length")
0135
0136 #undef C
0137 #define C(a, b, c) CXL_MBOX_CMD_RC_##a
0138 enum { CMD_CMD_RC_TABLE };
0139 #undef C
0140 #define C(a, b, c) { b, c }
0141 struct cxl_mbox_cmd_rc {
0142 int err;
0143 const char *desc;
0144 };
0145
0146 static const
0147 struct cxl_mbox_cmd_rc cxl_mbox_cmd_rctable[] ={ CMD_CMD_RC_TABLE };
0148 #undef C
0149
0150 static inline const char *cxl_mbox_cmd_rc2str(struct cxl_mbox_cmd *mbox_cmd)
0151 {
0152 return cxl_mbox_cmd_rctable[mbox_cmd->return_code].desc;
0153 }
0154
0155 static inline int cxl_mbox_cmd_rc2errno(struct cxl_mbox_cmd *mbox_cmd)
0156 {
0157 return cxl_mbox_cmd_rctable[mbox_cmd->return_code].err;
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167 #define CXL_CAPACITY_MULTIPLIER SZ_256M
0168
0169
0170
0171
0172
0173
0174
0175 struct cxl_endpoint_dvsec_info {
0176 bool mem_enabled;
0177 int ranges;
0178 struct range dvsec_range[2];
0179 };
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 struct cxl_dev_state {
0220 struct device *dev;
0221
0222 struct cxl_regs regs;
0223 int cxl_dvsec;
0224
0225 size_t payload_size;
0226 size_t lsa_size;
0227 struct mutex mbox_mutex;
0228 char firmware_version[0x10];
0229 DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX);
0230 DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
0231
0232 struct resource dpa_res;
0233 struct resource pmem_res;
0234 struct resource ram_res;
0235 u64 total_bytes;
0236 u64 volatile_only_bytes;
0237 u64 persistent_only_bytes;
0238 u64 partition_align_bytes;
0239
0240 u64 active_volatile_bytes;
0241 u64 active_persistent_bytes;
0242 u64 next_volatile_bytes;
0243 u64 next_persistent_bytes;
0244
0245 resource_size_t component_reg_phys;
0246 u64 serial;
0247
0248 struct xarray doe_mbs;
0249
0250 int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd);
0251 };
0252
0253 enum cxl_opcode {
0254 CXL_MBOX_OP_INVALID = 0x0000,
0255 CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID,
0256 CXL_MBOX_OP_GET_FW_INFO = 0x0200,
0257 CXL_MBOX_OP_ACTIVATE_FW = 0x0202,
0258 CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400,
0259 CXL_MBOX_OP_GET_LOG = 0x0401,
0260 CXL_MBOX_OP_IDENTIFY = 0x4000,
0261 CXL_MBOX_OP_GET_PARTITION_INFO = 0x4100,
0262 CXL_MBOX_OP_SET_PARTITION_INFO = 0x4101,
0263 CXL_MBOX_OP_GET_LSA = 0x4102,
0264 CXL_MBOX_OP_SET_LSA = 0x4103,
0265 CXL_MBOX_OP_GET_HEALTH_INFO = 0x4200,
0266 CXL_MBOX_OP_GET_ALERT_CONFIG = 0x4201,
0267 CXL_MBOX_OP_SET_ALERT_CONFIG = 0x4202,
0268 CXL_MBOX_OP_GET_SHUTDOWN_STATE = 0x4203,
0269 CXL_MBOX_OP_SET_SHUTDOWN_STATE = 0x4204,
0270 CXL_MBOX_OP_GET_POISON = 0x4300,
0271 CXL_MBOX_OP_INJECT_POISON = 0x4301,
0272 CXL_MBOX_OP_CLEAR_POISON = 0x4302,
0273 CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303,
0274 CXL_MBOX_OP_SCAN_MEDIA = 0x4304,
0275 CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305,
0276 CXL_MBOX_OP_MAX = 0x10000
0277 };
0278
0279 #define DEFINE_CXL_CEL_UUID \
0280 UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96, 0xb1, 0x62, \
0281 0x3b, 0x3f, 0x17)
0282
0283 #define DEFINE_CXL_VENDOR_DEBUG_UUID \
0284 UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6, 0x07, 0x19, \
0285 0x40, 0x3d, 0x86)
0286
0287 struct cxl_mbox_get_supported_logs {
0288 __le16 entries;
0289 u8 rsvd[6];
0290 struct cxl_gsl_entry {
0291 uuid_t uuid;
0292 __le32 size;
0293 } __packed entry[];
0294 } __packed;
0295
0296 struct cxl_cel_entry {
0297 __le16 opcode;
0298 __le16 effect;
0299 } __packed;
0300
0301 struct cxl_mbox_get_log {
0302 uuid_t uuid;
0303 __le32 offset;
0304 __le32 length;
0305 } __packed;
0306
0307
0308 struct cxl_mbox_identify {
0309 char fw_revision[0x10];
0310 __le64 total_capacity;
0311 __le64 volatile_capacity;
0312 __le64 persistent_capacity;
0313 __le64 partition_align;
0314 __le16 info_event_log_size;
0315 __le16 warning_event_log_size;
0316 __le16 failure_event_log_size;
0317 __le16 fatal_event_log_size;
0318 __le32 lsa_size;
0319 u8 poison_list_max_mer[3];
0320 __le16 inject_poison_limit;
0321 u8 poison_caps;
0322 u8 qos_telemetry_caps;
0323 } __packed;
0324
0325 struct cxl_mbox_get_partition_info {
0326 __le64 active_volatile_cap;
0327 __le64 active_persistent_cap;
0328 __le64 next_volatile_cap;
0329 __le64 next_persistent_cap;
0330 } __packed;
0331
0332 struct cxl_mbox_get_lsa {
0333 __le32 offset;
0334 __le32 length;
0335 } __packed;
0336
0337 struct cxl_mbox_set_lsa {
0338 __le32 offset;
0339 __le32 reserved;
0340 u8 data[];
0341 } __packed;
0342
0343 struct cxl_mbox_set_partition_info {
0344 __le64 volatile_capacity;
0345 u8 flags;
0346 } __packed;
0347
0348 #define CXL_SET_PARTITION_IMMEDIATE_FLAG BIT(0)
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 struct cxl_mem_command {
0368 struct cxl_command_info info;
0369 enum cxl_opcode opcode;
0370 u32 flags;
0371 #define CXL_CMD_FLAG_NONE 0
0372 #define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
0373 };
0374
0375 int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
0376 size_t in_size, void *out, size_t out_size);
0377 int cxl_dev_state_identify(struct cxl_dev_state *cxlds);
0378 int cxl_await_media_ready(struct cxl_dev_state *cxlds);
0379 int cxl_enumerate_cmds(struct cxl_dev_state *cxlds);
0380 int cxl_mem_create_range_info(struct cxl_dev_state *cxlds);
0381 struct cxl_dev_state *cxl_dev_state_create(struct device *dev);
0382 void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
0383 void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
0384 #ifdef CONFIG_CXL_SUSPEND
0385 void cxl_mem_active_inc(void);
0386 void cxl_mem_active_dec(void);
0387 #else
0388 static inline void cxl_mem_active_inc(void)
0389 {
0390 }
0391 static inline void cxl_mem_active_dec(void)
0392 {
0393 }
0394 #endif
0395
0396 struct cxl_hdm {
0397 struct cxl_component_regs regs;
0398 unsigned int decoder_count;
0399 unsigned int target_count;
0400 unsigned int interleave_mask;
0401 struct cxl_port *port;
0402 };
0403
0404 struct seq_file;
0405 struct dentry *cxl_debugfs_create_dir(const char *dir);
0406 void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
0407 #endif