@@ -9,6 +9,8 @@
#include <cxlmem.h>
#include <cxl.h>
+#include <uapi/fwctl/fwctl.h>
+
#include "core.h"
#include "trace.h"
@@ -573,6 +575,46 @@ int cxl_mailbox_user_commands_supported(struct cxl_mailbox *cxl_mbox)
}
EXPORT_SYMBOL_NS_GPL(cxl_mailbox_user_commands_supported, CXL);
+/**
+ * cxl_mailbox_user_commands_info_get() - Retrieve array of command info
+ * @cxl_mbox: cxl mailbox context
+ * @nr_cmds: number of commands to retrieve
+ * @outbuf: Output buffer to store array 'struct fwctl_command_info'
+ * @out_len: size of final output buffer
+ *
+ * Return: 0 for success, or -errno for failure.
+ */
+int cxl_mailbox_user_commands_info_get(struct cxl_mailbox *cxl_mbox, int nr_cmds,
+ void *outbuf, size_t *out_len)
+{
+ struct fwctl_command_info *entry;
+ struct cxl_command_info *info;
+ struct cxl_mem_command *cmd;
+
+ if (nr_cmds > FWCTL_CXL_MAX_COMMANDS)
+ return -EINVAL;
+
+ entry = outbuf;
+ for (int i = 0; i < nr_cmds; i++) {
+ cmd = fwctl_cxl_find_command(cxl_mbox, fwctl_command_sets[i]);
+ if (!cmd)
+ continue;
+ info = &cmd->info;
+ memset(entry, 0, sizeof(*entry));
+ entry->id = info->id;
+ entry->opcode = fwctl_command_sets[i];
+ entry->effects = info->effects;
+ entry->size_in = info->size_in;
+ entry->size_out = info->size_out;
+ entry++;
+ }
+
+ *out_len = sizeof(*entry) * nr_cmds;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_mailbox_user_commands_info_get, CXL);
+
int cxl_query_cmd(struct cxl_mailbox *cxl_mbox,
struct cxl_mem_query_commands __user *q)
{
@@ -53,6 +53,30 @@ static void *cxlctl_info(struct fwctl_uctx *uctx, size_t *length)
return info;
}
+static void *cxlctl_hw_info(struct fwctl_uctx *uctx, int commands, size_t *out_len)
+{
+ struct cxlctl_uctx *cxlctl_uctx =
+ container_of(uctx, struct cxlctl_uctx, uctx);
+ struct fwctl_device *fwctl = uctx->fwctl;
+ struct cxlctl_dev *cxlctl =
+ container_of(fwctl, struct cxlctl_dev, fwctl);
+ int rc;
+
+ if (commands > cxlctl_uctx->nr_commands)
+ return ERR_PTR(-EINVAL);
+
+ void *out __free(kvfree) = kvzalloc(*out_len, GFP_KERNEL);
+ if (!out)
+ return ERR_PTR(-ENOMEM);
+
+ rc = cxl_mailbox_user_commands_info_get(cxlctl->mbox,
+ commands, out, out_len);
+ if (rc)
+ return ERR_PTR(rc);
+
+ return_ptr(out);
+}
+
static void *cxlctl_fw_rpc(struct fwctl_uctx *uctx, enum fwctl_rpc_scope scope,
void *rpc_in, size_t in_len, size_t *out_len)
{
@@ -66,6 +90,7 @@ static const struct fwctl_ops cxlctl_ops = {
.open_uctx = cxlctl_open_uctx,
.close_uctx = cxlctl_close_uctx,
.info = cxlctl_info,
+ .hw_info = cxlctl_hw_info,
.fw_rpc = cxlctl_fw_rpc,
};
@@ -85,5 +85,7 @@ struct cxl_mailbox {
int cxl_mailbox_init(struct cxl_mailbox *cxl_mbox, struct device *host);
int cxl_mailbox_user_commands_supported(struct cxl_mailbox *cxl_mbox);
+int cxl_mailbox_user_commands_info_get(struct cxl_mailbox *cxl_mbox, int nr_cmds,
+ void *outbuf, size_t *out_len);
#endif
Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/cxl/core/mbox.c | 42 +++++++++++++++++++++++++++++++++++++++++ drivers/fwctl/cxl/cxl.c | 25 ++++++++++++++++++++++++ include/cxl/mailbox.h | 2 ++ 3 files changed, 69 insertions(+)