]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cxl: Add support to handle user feature commands for get feature
authorDave Jiang <dave.jiang@intel.com>
Fri, 7 Mar 2025 20:55:34 +0000 (13:55 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 17 Mar 2025 17:41:37 +0000 (14:41 -0300)
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>
drivers/cxl/core/features.c
include/uapi/fwctl/cxl.h

index 167d57809653d7031321321fcbdfa34943d821c1..88aceb3c8bec867fa4e60b7c98f45c0cc64e8e5c 100644 (file)
@@ -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);
        }
index 4bbfd772752646975da6dcd894ad6d663503b4e4..f589bfb774266bca42d9bb64d8a52e0849df365e 100644 (file)
@@ -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