Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /* Copyright(c) 2020-2021 Intel Corporation. */
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 /* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */
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  * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device
0034  * @dev: driver core device object
0035  * @cdev: char dev core object for ioctl operations
0036  * @cxlds: The device state backing this device
0037  * @detach_work: active memdev lost a port in its ancestry
0038  * @id: id number of this memdev instance.
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  * struct cxl_mbox_cmd - A command to be submitted to hardware.
0081  * @opcode: (input) The command set and command submitted to hardware.
0082  * @payload_in: (input) Pointer to the input payload.
0083  * @payload_out: (output) Pointer to the output payload. Must be allocated by
0084  *       the caller.
0085  * @size_in: (input) Number of bytes to load from @payload_in.
0086  * @size_out: (input) Max number of bytes loaded into @payload_out.
0087  *            (output) Number of bytes generated by the device. For fixed size
0088  *            outputs commands this is always expected to be deterministic. For
0089  *            variable sized output commands, it tells the exact number of bytes
0090  *            written.
0091  * @return_code: (output) Error code returned from hardware.
0092  *
0093  * This is the primary mechanism used to send commands to the hardware.
0094  * All the fields except @payload_* correspond exactly to the fields described in
0095  * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and
0096  * @payload_out are written to, and read from the Command Payload Registers
0097  * defined in CXL 2.0 8.2.8.4.8.
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  * Per CXL 2.0 Section 8.2.8.4.5.1
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  * CXL 2.0 - Memory capacity multiplier
0162  * See Section 8.2.9.5
0163  *
0164  * Volatile, Persistent, and Partition capacities are specified to be in
0165  * multiples of 256MB - define a multiplier to convert to/from bytes.
0166  */
0167 #define CXL_CAPACITY_MULTIPLIER SZ_256M
0168 
0169 /**
0170  * struct cxl_endpoint_dvsec_info - Cached DVSEC info
0171  * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
0172  * @ranges: Number of active HDM ranges this device uses.
0173  * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
0174  */
0175 struct cxl_endpoint_dvsec_info {
0176     bool mem_enabled;
0177     int ranges;
0178     struct range dvsec_range[2];
0179 };
0180 
0181 /**
0182  * struct cxl_dev_state - The driver device state
0183  *
0184  * cxl_dev_state represents the CXL driver/device state.  It provides an
0185  * interface to mailbox commands as well as some cached data about the device.
0186  * Currently only memory devices are represented.
0187  *
0188  * @dev: The device associated with this CXL state
0189  * @regs: Parsed register blocks
0190  * @cxl_dvsec: Offset to the PCIe device DVSEC
0191  * @payload_size: Size of space for payload
0192  *                (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register)
0193  * @lsa_size: Size of Label Storage Area
0194  *                (CXL 2.0 8.2.9.5.1.1 Identify Memory Device)
0195  * @mbox_mutex: Mutex to synchronize mailbox access.
0196  * @firmware_version: Firmware version for the memory device.
0197  * @enabled_cmds: Hardware commands found enabled in CEL.
0198  * @exclusive_cmds: Commands that are kernel-internal only
0199  * @dpa_res: Overall DPA resource tree for the device
0200  * @pmem_res: Active Persistent memory capacity configuration
0201  * @ram_res: Active Volatile memory capacity configuration
0202  * @total_bytes: sum of all possible capacities
0203  * @volatile_only_bytes: hard volatile capacity
0204  * @persistent_only_bytes: hard persistent capacity
0205  * @partition_align_bytes: alignment size for partition-able capacity
0206  * @active_volatile_bytes: sum of hard + soft volatile
0207  * @active_persistent_bytes: sum of hard + soft persistent
0208  * @next_volatile_bytes: volatile capacity change pending device reset
0209  * @next_persistent_bytes: persistent capacity change pending device reset
0210  * @component_reg_phys: register base of component registers
0211  * @info: Cached DVSEC information about the device.
0212  * @serial: PCIe Device Serial Number
0213  * @doe_mbs: PCI DOE mailbox array
0214  * @mbox_send: @dev specific transport for transmitting mailbox commands
0215  *
0216  * See section 8.2.9.5.2 Capacity Configuration and Label Storage for
0217  * details on capacity parameters.
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; /* Protects device mailbox and firmware */
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 /* See CXL 2.0 Table 175 Identify Memory Device Output Payload */
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  * struct cxl_mem_command - Driver representation of a memory device command
0352  * @info: Command information as it exists for the UAPI
0353  * @opcode: The actual bits used for the mailbox protocol
0354  * @flags: Set of flags effecting driver behavior.
0355  *
0356  *  * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag
0357  *    will be enabled by the driver regardless of what hardware may have
0358  *    advertised.
0359  *
0360  * The cxl_mem_command is the driver's internal representation of commands that
0361  * are supported by the driver. Some of these commands may not be supported by
0362  * the hardware. The driver will use @info to validate the fields passed in by
0363  * the user then submit the @opcode to the hardware.
0364  *
0365  * See struct cxl_command_info.
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 /* __CXL_MEM_H__ */