diff options
| author | Dave Jiang <dave.jiang@intel.com> | 2025-03-07 13:55:34 -0700 |
|---|---|---|
| committer | Jason Gunthorpe <jgg@nvidia.com> | 2025-03-17 14:41:37 -0300 |
| commit | 5908f3ed6dc209e5c824e63afda7545805f75a7e (patch) | |
| tree | 18fda1194ec52854971708225143169a9b9307a7 /drivers/cxl | |
| parent | 4d1c09cef2c244bd19467c016a3e56ba28ecc59d (diff) | |
| download | linux-5908f3ed6dc209e5c824e63afda7545805f75a7e.tar.gz linux-5908f3ed6dc209e5c824e63afda7545805f75a7e.tar.bz2 linux-5908f3ed6dc209e5c824e63afda7545805f75a7e.zip | |
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 <Jonathan.Cameron@huawei.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Li Ming <ming.li@zohomail.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/cxl')
| -rw-r--r-- | drivers/cxl/core/features.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/cxl/core/features.c b/drivers/cxl/core/features.c index 167d57809653..88aceb3c8bec 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); } |
