diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/cxl/features.h | 87 | ||||
| -rw-r--r-- | include/cxl/mailbox.h | 44 | ||||
| -rw-r--r-- | include/linux/fwctl.h | 135 | ||||
| -rw-r--r-- | include/linux/panic.h | 3 | ||||
| -rw-r--r-- | include/linux/pds/pds_adminq.h | 277 | ||||
| -rw-r--r-- | include/linux/pds/pds_common.h | 2 | ||||
| -rw-r--r-- | include/uapi/cxl/features.h | 170 | ||||
| -rw-r--r-- | include/uapi/fwctl/cxl.h | 56 | ||||
| -rw-r--r-- | include/uapi/fwctl/fwctl.h | 141 | ||||
| -rw-r--r-- | include/uapi/fwctl/mlx5.h | 36 | ||||
| -rw-r--r-- | include/uapi/fwctl/pds.h | 62 |
11 files changed, 1011 insertions, 2 deletions
diff --git a/include/cxl/features.h b/include/cxl/features.h new file mode 100644 index 000000000000..a3bb34694c06 --- /dev/null +++ b/include/cxl/features.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2024-2025 Intel Corporation. */ +#ifndef __CXL_FEATURES_H__ +#define __CXL_FEATURES_H__ + +#include <linux/uuid.h> +#include <linux/fwctl.h> +#include <uapi/cxl/features.h> + +/* Feature UUIDs used by the kernel */ +#define CXL_FEAT_PATROL_SCRUB_UUID \ + UUID_INIT(0x96dad7d6, 0xfde8, 0x482b, 0xa7, 0x33, 0x75, 0x77, 0x4e, \ + 0x06, 0xdb, 0x8a) + +#define CXL_FEAT_ECS_UUID \ + UUID_INIT(0xe5b13f22, 0x2328, 0x4a14, 0xb8, 0xba, 0xb9, 0x69, 0x1e, \ + 0x89, 0x33, 0x86) + +#define CXL_FEAT_SPPR_UUID \ + UUID_INIT(0x892ba475, 0xfad8, 0x474e, 0x9d, 0x3e, 0x69, 0x2c, 0x91, \ + 0x75, 0x68, 0xbb) + +#define CXL_FEAT_HPPR_UUID \ + UUID_INIT(0x80ea4521, 0x786f, 0x4127, 0xaf, 0xb1, 0xec, 0x74, 0x59, \ + 0xfb, 0x0e, 0x24) + +#define CXL_FEAT_CACHELINE_SPARING_UUID \ + UUID_INIT(0x96C33386, 0x91dd, 0x44c7, 0x9e, 0xcb, 0xfd, 0xaf, 0x65, \ + 0x03, 0xba, 0xc4) + +#define CXL_FEAT_ROW_SPARING_UUID \ + UUID_INIT(0x450ebf67, 0xb135, 0x4f97, 0xa4, 0x98, 0xc2, 0xd5, 0x7f, \ + 0x27, 0x9b, 0xed) + +#define CXL_FEAT_BANK_SPARING_UUID \ + UUID_INIT(0x78b79636, 0x90ac, 0x4b64, 0xa4, 0xef, 0xfa, 0xac, 0x5d, \ + 0x18, 0xa8, 0x63) + +#define CXL_FEAT_RANK_SPARING_UUID \ + UUID_INIT(0x34dbaff5, 0x0552, 0x4281, 0x8f, 0x76, 0xda, 0x0b, 0x5e, \ + 0x7a, 0x76, 0xa7) + +/* Feature commands capability supported by a device */ +enum cxl_features_capability { + CXL_FEATURES_NONE = 0, + CXL_FEATURES_RO, + CXL_FEATURES_RW, +}; + +/** + * struct cxl_features_state - The Features state for the device + * @cxlds: Pointer to CXL device state + * @entries: CXl feature entry context + */ +struct cxl_features_state { + struct cxl_dev_state *cxlds; + struct cxl_feat_entries { + int num_features; + int num_user_features; + struct cxl_feat_entry ent[] __counted_by(num_features); + } *entries; +}; + +struct cxl_mailbox; +struct cxl_memdev; +#ifdef CONFIG_CXL_FEATURES +inline struct cxl_features_state *to_cxlfs(struct cxl_dev_state *cxlds); +int devm_cxl_setup_features(struct cxl_dev_state *cxlds); +int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd); +#else +static inline struct cxl_features_state *to_cxlfs(struct cxl_dev_state *cxlds) +{ + return NULL; +} + +static inline int devm_cxl_setup_features(struct cxl_dev_state *cxlds) +{ + return -EOPNOTSUPP; +} + +static inline int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd) +{ + return -EOPNOTSUPP; +} +#endif + +#endif diff --git a/include/cxl/mailbox.h b/include/cxl/mailbox.h index bacd111e75f1..c4e99e2e3a9d 100644 --- a/include/cxl/mailbox.h +++ b/include/cxl/mailbox.h @@ -3,24 +3,66 @@ #ifndef __CXL_MBOX_H__ #define __CXL_MBOX_H__ #include <linux/rcuwait.h> +#include <cxl/features.h> +#include <uapi/linux/cxl_mem.h> -struct cxl_mbox_cmd; +/** + * struct cxl_mbox_cmd - A command to be submitted to hardware. + * @opcode: (input) The command set and command submitted to hardware. + * @payload_in: (input) Pointer to the input payload. + * @payload_out: (output) Pointer to the output payload. Must be allocated by + * the caller. + * @size_in: (input) Number of bytes to load from @payload_in. + * @size_out: (input) Max number of bytes loaded into @payload_out. + * (output) Number of bytes generated by the device. For fixed size + * outputs commands this is always expected to be deterministic. For + * variable sized output commands, it tells the exact number of bytes + * written. + * @min_out: (input) internal command output payload size validation + * @poll_count: (input) Number of timeouts to attempt. + * @poll_interval_ms: (input) Time between mailbox background command polling + * interval timeouts. + * @return_code: (output) Error code returned from hardware. + * + * This is the primary mechanism used to send commands to the hardware. + * All the fields except @payload_* correspond exactly to the fields described in + * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and + * @payload_out are written to, and read from the Command Payload Registers + * defined in CXL 2.0 8.2.8.4.8. + */ +struct cxl_mbox_cmd { + u16 opcode; + void *payload_in; + void *payload_out; + size_t size_in; + size_t size_out; + size_t min_out; + int poll_count; + int poll_interval_ms; + u16 return_code; +}; /** * struct cxl_mailbox - context for CXL mailbox operations * @host: device that hosts the mailbox + * @enabled_cmds: mailbox commands that are enabled by the driver + * @exclusive_cmds: mailbox commands that are exclusive to the kernel * @payload_size: Size of space for payload * (CXL 3.1 8.2.8.4.3 Mailbox Capabilities Register) * @mbox_mutex: mutex protects device mailbox and firmware * @mbox_wait: rcuwait for mailbox * @mbox_send: @dev specific transport for transmitting mailbox commands + * @feat_cap: Features capability */ struct cxl_mailbox { struct device *host; + DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX); + DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); size_t payload_size; struct mutex mbox_mutex; /* lock to protect mailbox context */ struct rcuwait mbox_wait; int (*mbox_send)(struct cxl_mailbox *cxl_mbox, struct cxl_mbox_cmd *cmd); + enum cxl_features_capability feat_cap; }; int cxl_mailbox_init(struct cxl_mailbox *cxl_mbox, struct device *host); diff --git a/include/linux/fwctl.h b/include/linux/fwctl.h new file mode 100644 index 000000000000..5d61fc8a6871 --- /dev/null +++ b/include/linux/fwctl.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES + */ +#ifndef __LINUX_FWCTL_H +#define __LINUX_FWCTL_H +#include <linux/device.h> +#include <linux/cdev.h> +#include <linux/cleanup.h> +#include <uapi/fwctl/fwctl.h> + +struct fwctl_device; +struct fwctl_uctx; + +/** + * struct fwctl_ops - Driver provided operations + * + * fwctl_unregister() will wait until all excuting ops are completed before it + * returns. Drivers should be mindful to not let their ops run for too long as + * it will block device hot unplug and module unloading. + */ +struct fwctl_ops { + /** + * @device_type: The drivers assigned device_type number. This is uABI. + */ + enum fwctl_device_type device_type; + /** + * @uctx_size: The size of the fwctl_uctx struct to allocate. The first + * bytes of this memory will be a fwctl_uctx. The driver can use the + * remaining bytes as its private memory. + */ + size_t uctx_size; + /** + * @open_uctx: Called when a file descriptor is opened before the uctx + * is ever used. + */ + int (*open_uctx)(struct fwctl_uctx *uctx); + /** + * @close_uctx: Called when the uctx is destroyed, usually when the FD + * is closed. + */ + void (*close_uctx)(struct fwctl_uctx *uctx); + /** + * @info: Implement FWCTL_INFO. Return a kmalloc() memory that is copied + * to out_device_data. On input length indicates the size of the user + * buffer on output it indicates the size of the memory. The driver can + * ignore length on input, the core code will handle everything. + */ + void *(*info)(struct fwctl_uctx *uctx, size_t *length); + /** + * @fw_rpc: Implement FWCTL_RPC. Deliver rpc_in/in_len to the FW and + * return the response and set out_len. rpc_in can be returned as the + * response pointer. Otherwise the returned pointer is freed with + * kvfree(). + */ + void *(*fw_rpc)(struct fwctl_uctx *uctx, enum fwctl_rpc_scope scope, + void *rpc_in, size_t in_len, size_t *out_len); +}; + +/** + * struct fwctl_device - Per-driver registration struct + * @dev: The sysfs (class/fwctl/fwctlXX) device + * + * Each driver instance will have one of these structs with the driver private + * data following immediately after. This struct is refcounted, it is freed by + * calling fwctl_put(). + */ +struct fwctl_device { + struct device dev; + /* private: */ + struct cdev cdev; + + /* Protect uctx_list */ + struct mutex uctx_list_lock; + struct list_head uctx_list; + /* + * Protect ops, held for write when ops becomes NULL during unregister, + * held for read whenever ops is loaded or an ops function is running. + */ + struct rw_semaphore registration_lock; + const struct fwctl_ops *ops; +}; + +struct fwctl_device *_fwctl_alloc_device(struct device *parent, + const struct fwctl_ops *ops, + size_t size); +/** + * fwctl_alloc_device - Allocate a fwctl + * @parent: Physical device that provides the FW interface + * @ops: Driver ops to register + * @drv_struct: 'struct driver_fwctl' that holds the struct fwctl_device + * @member: Name of the struct fwctl_device in @drv_struct + * + * This allocates and initializes the fwctl_device embedded in the drv_struct. + * Upon success the pointer must be freed via fwctl_put(). Returns a 'drv_struct + * \*' on success, NULL on error. + */ +#define fwctl_alloc_device(parent, ops, drv_struct, member) \ + ({ \ + static_assert(__same_type(struct fwctl_device, \ + ((drv_struct *)NULL)->member)); \ + static_assert(offsetof(drv_struct, member) == 0); \ + (drv_struct *)_fwctl_alloc_device(parent, ops, \ + sizeof(drv_struct)); \ + }) + +static inline struct fwctl_device *fwctl_get(struct fwctl_device *fwctl) +{ + get_device(&fwctl->dev); + return fwctl; +} +static inline void fwctl_put(struct fwctl_device *fwctl) +{ + put_device(&fwctl->dev); +} +DEFINE_FREE(fwctl, struct fwctl_device *, if (_T) fwctl_put(_T)); + +int fwctl_register(struct fwctl_device *fwctl); +void fwctl_unregister(struct fwctl_device *fwctl); + +/** + * struct fwctl_uctx - Per user FD context + * @fwctl: fwctl instance that owns the context + * + * Every FD opened by userspace will get a unique context allocation. Any driver + * private data will follow immediately after. + */ +struct fwctl_uctx { + struct fwctl_device *fwctl; + /* private: */ + /* Head at fwctl_device::uctx_list */ + struct list_head uctx_list_entry; +}; + +#endif diff --git a/include/linux/panic.h b/include/linux/panic.h index 54d90b6c5f47..2494d51707ef 100644 --- a/include/linux/panic.h +++ b/include/linux/panic.h @@ -74,7 +74,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout) #define TAINT_AUX 16 #define TAINT_RANDSTRUCT 17 #define TAINT_TEST 18 -#define TAINT_FLAGS_COUNT 19 +#define TAINT_FWCTL 19 +#define TAINT_FLAGS_COUNT 20 #define TAINT_FLAGS_MAX ((1UL << TAINT_FLAGS_COUNT) - 1) struct taint_flag { diff --git a/include/linux/pds/pds_adminq.h b/include/linux/pds/pds_adminq.h index 4b4e9a98b37b..ddd111f04ca0 100644 --- a/include/linux/pds/pds_adminq.h +++ b/include/linux/pds/pds_adminq.h @@ -1179,6 +1179,274 @@ struct pds_lm_host_vf_status_cmd { u8 status; }; +enum pds_fwctl_cmd_opcode { + PDS_FWCTL_CMD_IDENT = 70, + PDS_FWCTL_CMD_RPC = 71, + PDS_FWCTL_CMD_QUERY = 72, +}; + +/** + * struct pds_fwctl_cmd - Firmware control command structure + * @opcode: Opcode + * @rsvd: Reserved + * @ep: Endpoint identifier + * @op: Operation identifier + */ +struct pds_fwctl_cmd { + u8 opcode; + u8 rsvd[3]; + __le32 ep; + __le32 op; +} __packed; + +/** + * struct pds_fwctl_comp - Firmware control completion structure + * @status: Status of the firmware control operation + * @rsvd: Reserved + * @comp_index: Completion index in little-endian format + * @rsvd2: Reserved + * @color: Color bit indicating the state of the completion + */ +struct pds_fwctl_comp { + u8 status; + u8 rsvd; + __le16 comp_index; + u8 rsvd2[11]; + u8 color; +} __packed; + +/** + * struct pds_fwctl_ident_cmd - Firmware control identification command structure + * @opcode: Operation code for the command + * @rsvd: Reserved + * @version: Interface version + * @rsvd2: Reserved + * @len: Length of the identification data + * @ident_pa: Physical address of the identification data + */ +struct pds_fwctl_ident_cmd { + u8 opcode; + u8 rsvd; + u8 version; + u8 rsvd2; + __le32 len; + __le64 ident_pa; +} __packed; + +/* future feature bits here + * enum pds_fwctl_features { + * }; + * (compilers don't like empty enums) + */ + +/** + * struct pds_fwctl_ident - Firmware control identification structure + * @features: Supported features (enum pds_fwctl_features) + * @version: Interface version + * @rsvd: Reserved + * @max_req_sz: Maximum request size + * @max_resp_sz: Maximum response size + * @max_req_sg_elems: Maximum number of request SGs + * @max_resp_sg_elems: Maximum number of response SGs + */ +struct pds_fwctl_ident { + __le64 features; + u8 version; + u8 rsvd[3]; + __le32 max_req_sz; + __le32 max_resp_sz; + u8 max_req_sg_elems; + u8 max_resp_sg_elems; +} __packed; + +enum pds_fwctl_query_entity { + PDS_FWCTL_RPC_ROOT = 0, + PDS_FWCTL_RPC_ENDPOINT = 1, + PDS_FWCTL_RPC_OPERATION = 2, +}; + +#define PDS_FWCTL_RPC_OPCODE_CMD_SHIFT 0 +#define PDS_FWCTL_RPC_OPCODE_CMD_MASK GENMASK(15, PDS_FWCTL_RPC_OPCODE_CMD_SHIFT) +#define PDS_FWCTL_RPC_OPCODE_VER_SHIFT 16 +#define PDS_FWCTL_RPC_OPCODE_VER_MASK GENMASK(23, PDS_FWCTL_RPC_OPCODE_VER_SHIFT) + +#define PDS_FWCTL_RPC_OPCODE_GET_CMD(op) FIELD_GET(PDS_FWCTL_RPC_OPCODE_CMD_MASK, op) +#define PDS_FWCTL_RPC_OPCODE_GET_VER(op) FIELD_GET(PDS_FWCTL_RPC_OPCODE_VER_MASK, op) + +#define PDS_FWCTL_RPC_OPCODE_CMP(op1, op2) \ + (PDS_FWCTL_RPC_OPCODE_GET_CMD(op1) == PDS_FWCTL_RPC_OPCODE_GET_CMD(op2) && \ + PDS_FWCTL_RPC_OPCODE_GET_VER(op1) <= PDS_FWCTL_RPC_OPCODE_GET_VER(op2)) + +/* + * FW command attributes that map to the FWCTL scope values + */ +#define PDSFC_FW_CMD_ATTR_READ 0x00 +#define PDSFC_FW_CMD_ATTR_DEBUG_READ 0x02 +#define PDSFC_FW_CMD_ATTR_WRITE 0x04 +#define PDSFC_FW_CMD_ATTR_DEBUG_WRITE 0x08 +#define PDSFC_FW_CMD_ATTR_SYNC 0x10 + +/** + * struct pds_fwctl_query_cmd - Firmware control query command structure + * @opcode: Operation code for the command + * @entity: Entity type to query (enum pds_fwctl_query_entity) + * @version: Version of the query data structure supported by the driver + * @rsvd: Reserved + * @query_data_buf_len: Length of the query data buffer + * @query_data_buf_pa: Physical address of the query data buffer + * @ep: Endpoint identifier to query (when entity is PDS_FWCTL_RPC_ENDPOINT) + * @op: Operation identifier to query (when entity is PDS_FWCTL_RPC_OPERATION) + * + * This structure is used to send a query command to the firmware control + * interface. The structure is packed to ensure there is no padding between + * the fields. + */ +struct pds_fwctl_query_cmd { + u8 opcode; + u8 entity; + u8 version; + u8 rsvd; + __le32 query_data_buf_len; + __le64 query_data_buf_pa; + union { + __le32 ep; + __le32 op; + }; +} __packed; + +/** + * struct pds_fwctl_query_comp - Firmware control query completion structure + * @status: Status of the query command + * @rsvd: Reserved + * @comp_index: Completion index in little-endian format + * @version: Version of the query data structure returned by firmware. This + * should be less than or equal to the version supported by the driver + * @rsvd2: Reserved + * @color: Color bit indicating the state of the completion + */ +struct pds_fwctl_query_comp { + u8 status; + u8 rsvd; + __le16 comp_index; + u8 version; + u8 rsvd2[2]; + u8 color; +} __packed; + +/** + * struct pds_fwctl_query_data_endpoint - query data for entity PDS_FWCTL_RPC_ROOT + * @id: The identifier for the data endpoint + */ +struct pds_fwctl_query_data_endpoint { + __le32 id; +} __packed; + +/** + * struct pds_fwctl_query_data_operation - query data for entity PDS_FWCTL_RPC_ENDPOINT + * @id: Operation identifier + * @scope: Scope of the operation (enum fwctl_rpc_scope) + * @rsvd: Reserved + */ +struct pds_fwctl_query_data_operation { + __le32 id; + u8 scope; + u8 rsvd[3]; +} __packed; + +/** + * struct pds_fwctl_query_data - query data structure + * @version: Version of the query data structure + * @rsvd: Reserved + * @num_entries: Number of entries in the union + * @entries: Array of query data entries, depending on the entity type + */ +struct pds_fwctl_query_data { + u8 version; + u8 rsvd[3]; + __le32 num_entries; + u8 entries[] __counted_by_le(num_entries); +} __packed; + +/** + * struct pds_fwctl_rpc_cmd - Firmware control RPC command + * @opcode: opcode PDS_FWCTL_CMD_RPC + * @rsvd: Reserved + * @flags: Indicates indirect request and/or response handling + * @ep: Endpoint identifier + * @op: Operation identifier + * @inline_req0: Buffer for inline request + * @inline_req1: Buffer for inline request + * @req_pa: Physical address of request data + * @req_sz: Size of the request + * @req_sg_elems: Number of request SGs + * @req_rsvd: Reserved + * @inline_req2: Buffer for inline request + * @resp_pa: Physical address of response data + * @resp_sz: Size of the response + * @resp_sg_elems: Number of response SGs + * @resp_rsvd: Reserved + */ +struct pds_fwctl_rpc_cmd { + u8 opcode; + u8 rsvd; + __le16 flags; +#define PDS_FWCTL_RPC_IND_REQ 0x1 +#define PDS_FWCTL_RPC_IND_RESP 0x2 + __le32 ep; + __le32 op; + u8 inline_req0[16]; + union { + u8 inline_req1[16]; + struct { + __le64 req_pa; + __le32 req_sz; + u8 req_sg_elems; + u8 req_rsvd[3]; + }; + }; + union { + u8 inline_req2[16]; + struct { + __le64 resp_pa; + __le32 resp_sz; + u8 resp_sg_elems; + u8 resp_rsvd[3]; + }; + }; +} __packed; + +/** + * struct pds_sg_elem - Transmit scatter-gather (SG) descriptor element + * @addr: DMA address of SG element data buffer + * @len: Length of SG element data buffer, in bytes + * @rsvd: Reserved + */ +struct pds_sg_elem { + __le64 addr; + __le32 len; + u8 rsvd[4]; +} __packed; + +/** + * struct pds_fwctl_rpc_comp - Completion of a firmware control RPC + * @status: Status of the command + * @rsvd: Reserved + * @comp_index: Completion index of the command + * @err: Error code, if any, from the RPC + * @resp_sz: Size of the response + * @rsvd2: Reserved + * @color: Color bit indicating the state of the completion + */ +struct pds_fwctl_rpc_comp { + u8 status; + u8 rsvd; + __le16 comp_index; + __le32 err; + __le32 resp_sz; + u8 rsvd2[3]; + u8 color; +} __packed; + union pds_core_adminq_cmd { u8 opcode; u8 bytes[64]; @@ -1216,6 +1484,11 @@ union pds_core_adminq_cmd { struct pds_lm_dirty_enable_cmd lm_dirty_enable; struct pds_lm_dirty_disable_cmd lm_dirty_disable; struct pds_lm_dirty_seq_ack_cmd lm_dirty_seq_ack; + + struct pds_fwctl_cmd fwctl; + struct pds_fwctl_ident_cmd fwctl_ident; + struct pds_fwctl_rpc_cmd fwctl_rpc; + struct pds_fwctl_query_cmd fwctl_query; }; union pds_core_adminq_comp { @@ -1243,6 +1516,10 @@ union pds_core_adminq_comp { struct pds_lm_state_size_comp lm_state_size; struct pds_lm_dirty_status_comp lm_dirty_status; + + struct pds_fwctl_comp fwctl; + struct pds_fwctl_rpc_comp fwctl_rpc; + struct pds_fwctl_query_comp fwctl_query; }; #ifndef __CHECKER__ diff --git a/include/linux/pds/pds_common.h b/include/linux/pds/pds_common.h index 5802e1deef24..b193adbe7cc3 100644 --- a/include/linux/pds/pds_common.h +++ b/include/linux/pds/pds_common.h @@ -29,6 +29,7 @@ enum pds_core_vif_types { PDS_DEV_TYPE_ETH = 3, PDS_DEV_TYPE_RDMA = 4, PDS_DEV_TYPE_LM = 5, + PDS_DEV_TYPE_FWCTL = 6, /* new ones added before this line */ PDS_DEV_TYPE_MAX = 16 /* don't change - used in struct size */ @@ -40,6 +41,7 @@ enum pds_core_vif_types { #define PDS_DEV_TYPE_ETH_STR "Eth" #define PDS_DEV_TYPE_RDMA_STR "RDMA" #define PDS_DEV_TYPE_LM_STR "LM" +#define PDS_DEV_TYPE_FWCTL_STR "fwctl" #define PDS_VDPA_DEV_NAME PDS_CORE_DRV_NAME "." PDS_DEV_TYPE_VDPA_STR #define PDS_VFIO_LM_DEV_NAME PDS_CORE_DRV_NAME "." PDS_DEV_TYPE_LM_STR "." PDS_DEV_TYPE_VFIO_STR diff --git a/include/uapi/cxl/features.h b/include/uapi/cxl/features.h new file mode 100644 index 000000000000..d6db8984889f --- /dev/null +++ b/include/uapi/cxl/features.h @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2024,2025, Intel Corporation + * + * These are definitions for the mailbox command interface of CXL subsystem. + */ +#ifndef _UAPI_CXL_FEATURES_H_ +#define _UAPI_CXL_FEATURES_H_ + +#include <linux/types.h> +#ifndef __KERNEL__ +#include <uuid/uuid.h> +#else +#include <linux/uuid.h> +#endif + +/* + * struct cxl_mbox_get_sup_feats_in - Get Supported Features input + * + * @count: bytes of Feature data to return in output + * @start_idx: index of first requested Supported Feature Entry, 0 based. + * @reserved: reserved field, must be 0s. + * + * Get Supported Features (0x500h) CXL r3.2 8.2.9.6.1 command. + * Input block for Get support Feature + */ +struct cxl_mbox_get_sup_feats_in { + __le32 count; + __le16 start_idx; + __u8 reserved[2]; +} __attribute__ ((__packed__)); + +/* CXL spec r3.2 Table 8-87 command effects */ +#define CXL_CMD_CONFIG_CHANGE_COLD_RESET BIT(0) +#define CXL_CMD_CONFIG_CHANGE_IMMEDIATE BIT(1) +#define CXL_CMD_DATA_CHANGE_IMMEDIATE BIT(2) +#define CXL_CMD_POLICY_CHANGE_IMMEDIATE BIT(3) +#define CXL_CMD_LOG_CHANGE_IMMEDIATE BIT(4) +#define CXL_CMD_SECURITY_STATE_CHANGE BIT(5) +#define CXL_CMD_BACKGROUND BIT(6) +#define CXL_CMD_BGCMD_ABORT_SUPPORTED BIT(7) +#define CXL_CMD_EFFECTS_VALID BIT(9) +#define CXL_CMD_CONFIG_CHANGE_CONV_RESET BIT(10) +#define CXL_CMD_CONFIG_CHANGE_CXL_RESET BIT(11) +#define CXL_CMD_EFFECTS_RESERVED GENMASK(15, 12) + +/* + * struct cxl_feat_entry - Supported Feature Entry + * @uuid: UUID of the Feature + * @id: id to identify the feature. 0 based + * @get_feat_size: max bytes required for Get Feature command for this Feature + * @set_feat_size: max bytes required for Set Feature command for this Feature + * @flags: attribute flags + * @get_feat_ver: Get Feature version + * @set_feat_ver: Set Feature version + * @effects: Set Feature command effects + * @reserved: reserved, must be 0 + * + * CXL spec r3.2 Table 8-109 + * Get Supported Features Supported Feature Entry + */ +struct cxl_feat_entry { + uuid_t uuid; + __le16 id; + __le16 get_feat_size; + __le16 set_feat_size; + __le32 flags; + __u8 get_feat_ver; + __u8 set_feat_ver; + __le16 effects; + __u8 reserved[18]; +} __attribute__ ((__packed__)); + +/* @flags field for 'struct cxl_feat_entry' */ +#define CXL_FEATURE_F_CHANGEABLE BIT(0) +#define CXL_FEATURE_F_PERSIST_FW_UPDATE BIT(4) +#define CXL_FEATURE_F_DEFAULT_SEL BIT(5) +#define CXL_FEATURE_F_SAVED_SEL BIT(6) + +/* + * struct cxl_mbox_get_sup_feats_out - Get Supported Features output + * @num_entries: number of Supported Feature Entries returned + * @supported_feats: number of supported Features + * @reserved: reserved, must be 0s. + * @ents: Supported Feature Entries array + * + * CXL spec r3.2 Table 8-108 + * Get supported Features Output Payload + */ +struct cxl_mbox_get_sup_feats_out { + __struct_group(cxl_mbox_get_sup_feats_out_hdr, hdr, /* no attrs */, + __le16 num_entries; + __le16 supported_feats; + __u8 reserved[4]; + ); + struct cxl_feat_entry ents[] __counted_by_le(num_entries); +} __attribute__ ((__packed__)); + +/* + * Get Feature CXL spec r3.2 Spec 8.2.9.6.2 + */ + +/* + * struct cxl_mbox_get_feat_in - Get Feature input + * @uuid: UUID for Feature + * @offset: offset of the first byte in Feature data for output payload + * @count: count in bytes of Feature data returned + * @selection: 0 current value, 1 default value, 2 saved value + * + * CXL spec r3.2 section 8.2.9.6.2 Table 8-99 + */ +struct cxl_mbox_get_feat_in { + uuid_t uuid; + __le16 offset; + __le16 count; + __u8 selection; +} __attribute__ ((__packed__)); + +/* + * enum cxl_get_feat_selection - selection field of Get Feature input + */ +enum cxl_get_feat_selection { + CXL_GET_FEAT_SEL_CURRENT_VALUE, + CXL_GET_FEAT_SEL_DEFAULT_VALUE, + CXL_GET_FEAT_SEL_SAVED_VALUE, + CXL_GET_FEAT_SEL_MAX +}; + +/* + * Set Feature CXL spec r3.2 8.2.9.6.3 + */ + +/* + * struct cxl_mbox_set_feat_in - Set Features input + * @uuid: UUID for Feature + * @flags: set feature flags + * @offset: byte offset of Feature data to update + * @version: Feature version of the data in Feature Data + * @rsvd: reserved, must be 0s. + * @feat_data: raw byte stream of Features data to update + * + * CXL spec r3.2 section 8.2.9.6.3 Table 8-101 + */ +struct cxl_mbox_set_feat_in { + __struct_group(cxl_mbox_set_feat_hdr, hdr, /* no attrs */, + uuid_t uuid; + __le32 flags; + __le16 offset; + __u8 version; + __u8 rsvd[9]; + ); + __u8 feat_data[]; +} __packed; + +/* + * enum cxl_set_feat_flag_data_transfer - Set Feature flags field + */ +enum cxl_set_feat_flag_data_transfer { + CXL_SET_FEAT_FLAG_FULL_DATA_TRANSFER = 0, + CXL_SET_FEAT_FLAG_INITIATE_DATA_TRANSFER, + CXL_SET_FEAT_FLAG_CONTINUE_DATA_TRANSFER, + CXL_SET_FEAT_FLAG_FINISH_DATA_TRANSFER, + CXL_SET_FEAT_FLAG_ABORT_DATA_TRANSFER, + CXL_SET_FEAT_FLAG_DATA_TRANSFER_MAX +}; + +#define CXL_SET_FEAT_FLAG_DATA_TRANSFER_MASK GENMASK(2, 0) +#define CXL_SET_FEAT_FLAG_DATA_SAVED_ACROSS_RESET BIT(3) + +#endif diff --git a/include/uapi/fwctl/cxl.h b/include/uapi/fwctl/cxl.h new file mode 100644 index 000000000000..43f522f0cdcd --- /dev/null +++ b/include/uapi/fwctl/cxl.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2024-2025 Intel Corporation + * + * These are definitions for the mailbox command interface of CXL subsystem. + */ +#ifndef _UAPI_FWCTL_CXL_H_ +#define _UAPI_FWCTL_CXL_H_ + +#include <linux/types.h> +#include <linux/stddef.h> +#include <cxl/features.h> + +/** + * struct fwctl_rpc_cxl - ioctl(FWCTL_RPC) input for CXL + * @opcode: CXL mailbox command opcode + * @flags: Flags for the command (input). + * @op_size: Size of input payload. + * @reserved1: Reserved. Must be 0s. + * @get_sup_feats_in: Get Supported Features input + * @get_feat_in: Get Feature input + * @set_feat_in: Set Feature input + */ +struct fwctl_rpc_cxl { + __struct_group(fwctl_rpc_cxl_hdr, hdr, /* no attrs */, + __u32 opcode; + __u32 flags; + __u32 op_size; + __u32 reserved1; + ); + union { + struct cxl_mbox_get_sup_feats_in get_sup_feats_in; + struct cxl_mbox_get_feat_in get_feat_in; + struct cxl_mbox_set_feat_in set_feat_in; + }; +}; + +/** + * struct fwctl_rpc_cxl_out - ioctl(FWCTL_RPC) output for CXL + * @size: Size of the output payload + * @retval: Return value from device + * @get_sup_feats_out: Get Supported Features output + * @payload: raw byte stream of payload + */ +struct fwctl_rpc_cxl_out { + __struct_group(fwctl_rpc_cxl_out_hdr, hdr, /* no attrs */, + __u32 size; + __u32 retval; + ); + union { + struct cxl_mbox_get_sup_feats_out get_sup_feats_out; + __DECLARE_FLEX_ARRAY(__u8, payload); + }; +}; + +#endif diff --git a/include/uapi/fwctl/fwctl.h b/include/uapi/fwctl/fwctl.h new file mode 100644 index 000000000000..716ac0eee42d --- /dev/null +++ b/include/uapi/fwctl/fwctl.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. + */ +#ifndef _UAPI_FWCTL_H +#define _UAPI_FWCTL_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define FWCTL_TYPE 0x9A + +/** + * DOC: General ioctl format + * + * The ioctl interface follows a general format to allow for extensibility. Each + * ioctl is passed a structure pointer as the argument providing the size of + * the structure in the first u32. The kernel checks that any structure space + * beyond what it understands is 0. This allows userspace to use the backward + * compatible portion while consistently using the newer, larger, structures. + * + * ioctls use a standard meaning for common errnos: + * + * - ENOTTY: The IOCTL number itself is not supported at all + * - E2BIG: The IOCTL number is supported, but the provided structure has + * non-zero in a part the kernel does not understand. + * - EOPNOTSUPP: The IOCTL number is supported, and the structure is + * understood, however a known field has a value the kernel does not + * understand or support. + * - EINVAL: Everything about the IOCTL was understood, but a field is not + * correct. + * - ENOMEM: Out of memory. + * - ENODEV: The underlying device has been hot-unplugged and the FD is + * orphaned. + * + * As well as additional errnos, within specific ioctls. + */ +enum { + FWCTL_CMD_BASE = 0, + FWCTL_CMD_INFO = 0, + FWCTL_CMD_RPC = 1, +}; + +enum fwctl_device_type { + FWCTL_DEVICE_TYPE_ERROR = 0, + FWCTL_DEVICE_TYPE_MLX5 = 1, + FWCTL_DEVICE_TYPE_CXL = 2, + FWCTL_DEVICE_TYPE_PDS = 4, +}; + +/** + * struct fwctl_info - ioctl(FWCTL_INFO) + * @size: sizeof(struct fwctl_info) + * @flags: Must be 0 + * @out_device_type: Returns the type of the device from enum fwctl_device_type + * @device_data_len: On input the length of the out_device_data memory. On + * output the size of the kernel's device_data which may be larger or + * smaller than the input. Maybe 0 on input. + * @out_device_data: Pointer to a memory of device_data_len bytes. Kernel will + * fill the entire memory, zeroing as required. + * + * Returns basic information about this fwctl instance, particularly what driver + * is being used to define the device_data format. + */ +struct fwctl_info { + __u32 size; + __u32 flags; + __u32 out_device_type; + __u32 device_data_len; + __aligned_u64 out_device_data; +}; +#define FWCTL_INFO _IO(FWCTL_TYPE, FWCTL_CMD_INFO) + +/** + * enum fwctl_rpc_scope - Scope of access for the RPC + * + * Refer to fwctl.rst for a more detailed discussion of these scopes. + */ +enum fwctl_rpc_scope { + /** + * @FWCTL_RPC_CONFIGURATION: Device configuration access scope + * + * Read/write access to device configuration. When configuration + * is written to the device it remains in a fully supported state. + */ + FWCTL_RPC_CONFIGURATION = 0, + /** + * @FWCTL_RPC_DEBUG_READ_ONLY: Read only access to debug information + * + * Readable debug information. Debug information is compatible with + * kernel lockdown, and does not disclose any sensitive information. For + * instance exposing any encryption secrets from this information is + * forbidden. + */ + FWCTL_RPC_DEBUG_READ_ONLY = 1, + /** + * @FWCTL_RPC_DEBUG_WRITE: Writable access to lockdown compatible debug information + * + * Allows write access to data in the device which may leave a fully + * supported state. This is intended to permit intensive and possibly + * invasive debugging. This scope will taint the kernel. + */ + FWCTL_RPC_DEBUG_WRITE = 2, + /** + * @FWCTL_RPC_DEBUG_WRITE_FULL: Write access to all debug information + * + * Allows read/write access to everything. Requires CAP_SYS_RAW_IO, so + * it is not required to follow lockdown principals. If in doubt + * debugging should be placed in this scope. This scope will taint the + * kernel. + */ + FWCTL_RPC_DEBUG_WRITE_FULL = 3, +}; + +/** + * struct fwctl_rpc - ioctl(FWCTL_RPC) + * @size: sizeof(struct fwctl_rpc) + * @scope: One of enum fwctl_rpc_scope, required scope for the RPC + * @in_len: Length of the in memory + * @out_len: Length of the out memory + * @in: Request message in device specific format + * @out: Response message in device specific format + * + * Deliver a Remote Procedure Call to the device FW and return the response. The + * call's parameters and return are marshaled into linear buffers of memory. Any + * errno indicates that delivery of the RPC to the device failed. Return status + * originating in the device during a successful delivery must be encoded into + * out. + * + * The format of the buffers matches the out_device_type from FWCTL_INFO. + */ +struct fwctl_rpc { + __u32 size; + __u32 scope; + __u32 in_len; + __u32 out_len; + __aligned_u64 in; + __aligned_u64 out; +}; +#define FWCTL_RPC _IO(FWCTL_TYPE, FWCTL_CMD_RPC) + +#endif diff --git a/include/uapi/fwctl/mlx5.h b/include/uapi/fwctl/mlx5.h new file mode 100644 index 000000000000..625819180ac6 --- /dev/null +++ b/include/uapi/fwctl/mlx5.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES + * + * These are definitions for the command interface for mlx5 HW. mlx5 FW has a + * User Context mechanism which allows the FW to understand a security scope. + * FWCTL binds each FD to a FW user context and then places the User Context ID + * (UID) in each command header. The created User Context has a capability set + * that is appropriate for FWCTL's security model. + * + * Command formation should use a copy of the structs in mlx5_ifc.h following + * the Programmers Reference Manual. A open release is available here: + * + * https://network.nvidia.com/files/doc-2020/ethernet-adapters-programming-manual.pdf + * + * The device_type for this file is FWCTL_DEVICE_TYPE_MLX5. + */ +#ifndef _UAPI_FWCTL_MLX5_H +#define _UAPI_FWCTL_MLX5_H + +#include <linux/types.h> + +/** + * struct fwctl_info_mlx5 - ioctl(FWCTL_INFO) out_device_data + * @uid: The FW UID this FD is bound to. Each command header will force + * this value. + * @uctx_caps: The FW capabilities that are enabled for the uid. + * + * Return basic information about the FW interface available. + */ +struct fwctl_info_mlx5 { + __u32 uid; + __u32 uctx_caps; +}; + +#endif diff --git a/include/uapi/fwctl/pds.h b/include/uapi/fwctl/pds.h new file mode 100644 index 000000000000..66be32411642 --- /dev/null +++ b/include/uapi/fwctl/pds.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright(c) Advanced Micro Devices, Inc */ + +/* + * fwctl interface info for pds_fwctl + */ + +#ifndef _UAPI_FWCTL_PDS_H_ +#define _UAPI_FWCTL_PDS_H_ + +#include <linux/types.h> + +/** + * struct fwctl_info_pds + * @uctx_caps: bitmap of firmware capabilities + * + * Return basic information about the FW interface available. + */ +struct fwctl_info_pds { + __u32 uctx_caps; +}; + +/** + * enum pds_fwctl_capabilities + * @PDS_FWCTL_QUERY_CAP: firmware can be queried for information + * @PDS_FWCTL_SEND_CAP: firmware can be sent commands + */ +enum pds_fwctl_capabilities { + PDS_FWCTL_QUERY_CAP = 0, + PDS_FWCTL_SEND_CAP, +}; + +/** + * struct fwctl_rpc_pds + * @in.op: requested operation code + * @in.ep: firmware endpoint to operate on + * @in.rsvd: reserved + * @in.len: length of payload data + * @in.payload: address of payload buffer + * @in: rpc in parameters + * @out.retval: operation result value + * @out.rsvd: reserved + * @out.len: length of result data buffer + * @out.payload: address of payload data buffer + * @out: rpc out parameters + */ +struct fwctl_rpc_pds { + struct { + __u32 op; + __u32 ep; + __u32 rsvd; + __u32 len; + __aligned_u64 payload; + } in; + struct { + __u32 retval; + __u32 rsvd[2]; + __u32 len; + __aligned_u64 payload; + } out; +}; +#endif /* _UAPI_FWCTL_PDS_H_ */ |
