From: Dave Jiang Date: Fri, 7 Mar 2025 20:55:34 +0000 (-0700) Subject: cxl: Add support to handle user feature commands for get feature X-Git-Tag: v6.15-rc1~117^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5908f3ed6dc209e5c824e63afda7545805f75a7e;p=thirdparty%2Flinux.git cxl: Add support to handle user feature commands for get feature Add helper function to parse the user data from fwctl RPC ioctl and send the parsed input parameters to cxl_get_feature() call. Link: https://patch.msgid.link/r/20250307205648.1021626-5-dave.jiang@intel.com Reviewed-by: Jonathan Cameron Reviewed-by: Dan Williams Reviewed-by: Li Ming Signed-off-by: Dave Jiang Signed-off-by: Jason Gunthorpe --- diff --git a/drivers/cxl/core/features.c b/drivers/cxl/core/features.c index 167d57809653d..88aceb3c8bec8 100644 --- a/drivers/cxl/core/features.c +++ b/drivers/cxl/core/features.c @@ -427,6 +427,47 @@ static void *cxlctl_get_supported_features(struct cxl_features_state *cxlfs, return no_free_ptr(rpc_out); } +static void *cxlctl_get_feature(struct cxl_features_state *cxlfs, + const struct fwctl_rpc_cxl *rpc_in, + size_t *out_len) +{ + struct cxl_mailbox *cxl_mbox = &cxlfs->cxlds->cxl_mbox; + const struct cxl_mbox_get_feat_in *feat_in; + u16 offset, count, return_code; + size_t out_size = *out_len; + + if (rpc_in->op_size != sizeof(*feat_in)) + return ERR_PTR(-EINVAL); + + feat_in = &rpc_in->get_feat_in; + offset = le16_to_cpu(feat_in->offset); + count = le16_to_cpu(feat_in->count); + + if (!count) + return ERR_PTR(-EINVAL); + + struct fwctl_rpc_cxl_out *rpc_out __free(kvfree) = + kvzalloc(out_size, GFP_KERNEL); + if (!rpc_out) + return ERR_PTR(-ENOMEM); + + out_size = cxl_get_feature(cxl_mbox, &feat_in->uuid, + feat_in->selection, rpc_out->payload, + count, offset, &return_code); + *out_len = sizeof(struct fwctl_rpc_cxl_out); + if (!out_size) { + rpc_out->size = 0; + rpc_out->retval = return_code; + return no_free_ptr(rpc_out); + } + + rpc_out->size = out_size; + rpc_out->retval = CXL_MBOX_CMD_RC_SUCCESS; + *out_len += out_size; + + return no_free_ptr(rpc_out); +} + static bool cxlctl_validate_hw_command(struct cxl_features_state *cxlfs, const struct fwctl_rpc_cxl *rpc_in, enum fwctl_rpc_scope scope, @@ -436,6 +477,7 @@ static bool cxlctl_validate_hw_command(struct cxl_features_state *cxlfs, switch (opcode) { case CXL_MBOX_OP_GET_SUPPORTED_FEATURES: + case CXL_MBOX_OP_GET_FEATURE: if (cxl_mbox->feat_cap < CXL_FEATURES_RO) return false; if (scope >= FWCTL_RPC_CONFIGURATION) @@ -453,6 +495,8 @@ static void *cxlctl_handle_commands(struct cxl_features_state *cxlfs, switch (opcode) { case CXL_MBOX_OP_GET_SUPPORTED_FEATURES: return cxlctl_get_supported_features(cxlfs, rpc_in, out_len); + case CXL_MBOX_OP_GET_FEATURE: + return cxlctl_get_feature(cxlfs, rpc_in, out_len); default: return ERR_PTR(-EOPNOTSUPP); } diff --git a/include/uapi/fwctl/cxl.h b/include/uapi/fwctl/cxl.h index 4bbfd77275264..f589bfb774266 100644 --- a/include/uapi/fwctl/cxl.h +++ b/include/uapi/fwctl/cxl.h @@ -18,6 +18,7 @@ * @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 */ struct fwctl_rpc_cxl { __struct_group(fwctl_rpc_cxl_hdr, hdr, /* no attrs */, @@ -26,7 +27,10 @@ struct fwctl_rpc_cxl { __u32 op_size; __u32 reserved1; ); - struct cxl_mbox_get_sup_feats_in get_sup_feats_in; + union { + struct cxl_mbox_get_sup_feats_in get_sup_feats_in; + struct cxl_mbox_get_feat_in get_feat_in; + }; }; /** @@ -34,13 +38,17 @@ struct fwctl_rpc_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; ); - struct cxl_mbox_get_sup_feats_out get_sup_feats_out; + union { + struct cxl_mbox_get_sup_feats_out get_sup_feats_out; + __DECLARE_FLEX_ARRAY(__u8, payload); + }; }; #endif