]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl: Enumerate feature commands
authorDave Jiang <dave.jiang@intel.com>
Thu, 20 Feb 2025 19:42:39 +0000 (12:42 -0700)
committerDave Jiang <dave.jiang@intel.com>
Wed, 26 Feb 2025 15:49:41 +0000 (08:49 -0700)
Add feature commands enumeration code in order to detect and enumerate
the 3 feature related commands "get supported features", "get feature",
and "set feature". The enumeration will help determine whether the driver
can issue any of the 3 commands to the device.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Li Ming <ming.li@zohomail.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Tested-by: Shiju Jose <shiju.jose@huawei.com>
Link: https://patch.msgid.link/20250220194438.2281088-2-dave.jiang@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/mbox.c
drivers/cxl/cxlmem.h
include/cxl/features.h [new file with mode: 0644]
include/cxl/mailbox.h

index 9c1b9e353e3e3f4589b137ba20fe0710c6e9eee4..78c5346e3e891bd591909005a46c5bb826dbe2ac 100644 (file)
@@ -706,6 +706,35 @@ static int cxl_xfer_log(struct cxl_memdev_state *mds, uuid_t *uuid,
        return 0;
 }
 
+static int check_features_opcodes(u16 opcode, int *ro_cmds, int *wr_cmds)
+{
+       switch (opcode) {
+       case CXL_MBOX_OP_GET_SUPPORTED_FEATURES:
+       case CXL_MBOX_OP_GET_FEATURE:
+               (*ro_cmds)++;
+               return 1;
+       case CXL_MBOX_OP_SET_FEATURE:
+               (*wr_cmds)++;
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/* 'Get Supported Features' and 'Get Feature' */
+#define MAX_FEATURES_READ_CMDS 2
+static void set_features_cap(struct cxl_mailbox *cxl_mbox,
+                            int ro_cmds, int wr_cmds)
+{
+       /* Setting up Features capability while walking the CEL */
+       if (ro_cmds == MAX_FEATURES_READ_CMDS) {
+               if (wr_cmds)
+                       cxl_mbox->feat_cap = CXL_FEATURES_RW;
+               else
+                       cxl_mbox->feat_cap = CXL_FEATURES_RO;
+       }
+}
+
 /**
  * cxl_walk_cel() - Walk through the Command Effects Log.
  * @mds: The driver data for the operation
@@ -721,7 +750,7 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
        struct cxl_cel_entry *cel_entry;
        const int cel_entries = size / sizeof(*cel_entry);
        struct device *dev = mds->cxlds.dev;
-       int i;
+       int i, ro_cmds = 0, wr_cmds = 0;
 
        cel_entry = (struct cxl_cel_entry *) cel;
 
@@ -735,6 +764,9 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
                        enabled++;
                }
 
+               enabled += check_features_opcodes(opcode, &ro_cmds,
+                                                 &wr_cmds);
+
                if (cxl_is_poison_command(opcode)) {
                        cxl_set_poison_cmd_enabled(&mds->poison, opcode);
                        enabled++;
@@ -748,6 +780,8 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
                dev_dbg(dev, "Opcode 0x%04x %s\n", opcode,
                        enabled ? "enabled" : "unsupported by driver");
        }
+
+       set_features_cap(cxl_mbox, ro_cmds, wr_cmds);
 }
 
 static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_memdev_state *mds)
index a0a49809cd76c3acf6879a4061f9a5ca7efaad13..55c55685cb39f9f7b2da2df1ba166f3124a191d9 100644 (file)
@@ -490,6 +490,9 @@ enum cxl_opcode {
        CXL_MBOX_OP_GET_LOG_CAPS        = 0x0402,
        CXL_MBOX_OP_CLEAR_LOG           = 0x0403,
        CXL_MBOX_OP_GET_SUP_LOG_SUBLIST = 0x0405,
+       CXL_MBOX_OP_GET_SUPPORTED_FEATURES      = 0x0500,
+       CXL_MBOX_OP_GET_FEATURE         = 0x0501,
+       CXL_MBOX_OP_SET_FEATURE         = 0x0502,
        CXL_MBOX_OP_IDENTIFY            = 0x4000,
        CXL_MBOX_OP_GET_PARTITION_INFO  = 0x4100,
        CXL_MBOX_OP_SET_PARTITION_INFO  = 0x4101,
diff --git a/include/cxl/features.h b/include/cxl/features.h
new file mode 100644 (file)
index 0000000..357d3ac
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2024-2025 Intel Corporation. */
+#ifndef __CXL_FEATURES_H__
+#define __CXL_FEATURES_H__
+
+/* Feature commands capability supported by a device */
+enum cxl_features_capability {
+       CXL_FEATURES_NONE = 0,
+       CXL_FEATURES_RO,
+       CXL_FEATURES_RW,
+};
+
+#endif
index cc894f07a435180f3d265250b1b90f1cc460787f..c4e99e2e3a9d47434924fee4bd22b9808b1b1dd3 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef __CXL_MBOX_H__
 #define __CXL_MBOX_H__
 #include <linux/rcuwait.h>
+#include <cxl/features.h>
 #include <uapi/linux/cxl_mem.h>
 
 /**
@@ -51,6 +52,7 @@ struct cxl_mbox_cmd {
  * @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;
@@ -60,6 +62,7 @@ struct cxl_mailbox {
        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);