xref: /linux/Documentation/userspace-api/fwctl/fwctl-cxl.rst (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1*72b24a9dSDave Jiang.. SPDX-License-Identifier: GPL-2.0
2*72b24a9dSDave Jiang
3*72b24a9dSDave Jiang================
4*72b24a9dSDave Jiangfwctl cxl driver
5*72b24a9dSDave Jiang================
6*72b24a9dSDave Jiang
7*72b24a9dSDave Jiang:Author: Dave Jiang
8*72b24a9dSDave Jiang
9*72b24a9dSDave JiangOverview
10*72b24a9dSDave Jiang========
11*72b24a9dSDave Jiang
12*72b24a9dSDave JiangThe CXL spec defines a set of commands that can be issued to the mailbox of a
13*72b24a9dSDave JiangCXL device or switch. It also left room for vendor specific commands to be
14*72b24a9dSDave Jiangissued to the mailbox as well. fwctl provides a path to issue a set of allowed
15*72b24a9dSDave Jiangmailbox commands from user space to the device moderated by the kernel driver.
16*72b24a9dSDave Jiang
17*72b24a9dSDave JiangThe following 3 commands will be used to support CXL Features:
18*72b24a9dSDave JiangCXL spec r3.1 8.2.9.6.1 Get Supported Features (Opcode 0500h)
19*72b24a9dSDave JiangCXL spec r3.1 8.2.9.6.2 Get Feature (Opcode 0501h)
20*72b24a9dSDave JiangCXL spec r3.1 8.2.9.6.3 Set Feature (Opcode 0502h)
21*72b24a9dSDave Jiang
22*72b24a9dSDave JiangThe "Get Supported Features" return data may be filtered by the kernel driver to
23*72b24a9dSDave Jiangdrop any features that are forbidden by the kernel or being exclusively used by
24*72b24a9dSDave Jiangthe kernel. The driver will set the "Set Feature Size" of the "Get Supported
25*72b24a9dSDave JiangFeatures Supported Feature Entry" to 0 to indicate that the Feature cannot be
26*72b24a9dSDave Jiangmodified. The "Get Supported Features" command and the "Get Features" falls
27*72b24a9dSDave Jiangunder the fwctl policy of FWCTL_RPC_CONFIGURATION.
28*72b24a9dSDave Jiang
29*72b24a9dSDave JiangFor "Set Feature" command, the access policy currently is broken down into two
30*72b24a9dSDave Jiangcategories depending on the Set Feature effects reported by the device. If the
31*72b24a9dSDave JiangSet Feature will cause immediate change to the device, the fwctl access policy
32*72b24a9dSDave Jiangmust be FWCTL_RPC_DEBUG_WRITE_FULL. The effects for this level are
33*72b24a9dSDave Jiang"immediate config change", "immediate data change", "immediate policy change",
34*72b24a9dSDave Jiangor "immediate log change" for the set effects mask. If the effects are "config
35*72b24a9dSDave Jiangchange with cold reset" or "config change with conventional reset", then the
36*72b24a9dSDave Jiangfwctl access policy must be FWCTL_RPC_DEBUG_WRITE or higher.
37*72b24a9dSDave Jiang
38*72b24a9dSDave Jiangfwctl cxl User API
39*72b24a9dSDave Jiang==================
40*72b24a9dSDave Jiang
41*72b24a9dSDave Jiang.. kernel-doc:: include/uapi/fwctl/cxl.h
42*72b24a9dSDave Jiang
43*72b24a9dSDave Jiang1. Driver info query
44*72b24a9dSDave Jiang--------------------
45*72b24a9dSDave Jiang
46*72b24a9dSDave JiangFirst step for the app is to issue the ioctl(FWCTL_CMD_INFO). Successful
47*72b24a9dSDave Jianginvocation of the ioctl implies the Features capability is operational and
48*72b24a9dSDave Jiangreturns an all zeros 32bit payload. A ``struct fwctl_info`` needs to be filled
49*72b24a9dSDave Jiangout with the ``fwctl_info.out_device_type`` set to ``FWCTL_DEVICE_TYPE_CXL``.
50*72b24a9dSDave JiangThe return data should be ``struct fwctl_info_cxl`` that contains a reserved
51*72b24a9dSDave Jiang32bit field that should be all zeros.
52*72b24a9dSDave Jiang
53*72b24a9dSDave Jiang2. Send hardware commands
54*72b24a9dSDave Jiang-------------------------
55*72b24a9dSDave Jiang
56*72b24a9dSDave JiangNext step is to send the 'Get Supported Features' command to the driver from
57*72b24a9dSDave Jianguser space via ioctl(FWCTL_RPC). A ``struct fwctl_rpc_cxl`` is pointed to
58*72b24a9dSDave Jiangby ``fwctl_rpc.in``. ``struct fwctl_rpc_cxl.in_payload`` points to
59*72b24a9dSDave Jiangthe hardware input structure that is defined by the CXL spec. ``fwctl_rpc.out``
60*72b24a9dSDave Jiangpoints to the buffer that contains a ``struct fwctl_rpc_cxl_out`` that includes
61*72b24a9dSDave Jiangthe hardware output data inlined as ``fwctl_rpc_cxl_out.payload``. This command
62*72b24a9dSDave Jiangis called twice. First time to retrieve the number of features supported.
63*72b24a9dSDave JiangA second time to retrieve the specific feature details as the output data.
64*72b24a9dSDave Jiang
65*72b24a9dSDave JiangAfter getting the specific feature details, a Get/Set Feature command can be
66*72b24a9dSDave Jiangappropriately programmed and sent. For a "Set Feature" command, the retrieved
67*72b24a9dSDave Jiangfeature info contains an effects field that details the resulting
68*72b24a9dSDave Jiang"Set Feature" command will trigger. That will inform the user whether
69*72b24a9dSDave Jiangthe system is configured to allowed the "Set Feature" command or not.
70*72b24a9dSDave Jiang
71*72b24a9dSDave JiangCode example of a Get Feature
72*72b24a9dSDave Jiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73*72b24a9dSDave Jiang
74*72b24a9dSDave Jiang.. code-block:: c
75*72b24a9dSDave Jiang
76*72b24a9dSDave Jiang        static int cxl_fwctl_rpc_get_test_feature(int fd, struct test_feature *feat_ctx,
77*72b24a9dSDave Jiang                                                  const uint32_t expected_data)
78*72b24a9dSDave Jiang        {
79*72b24a9dSDave Jiang                struct cxl_mbox_get_feat_in *feat_in;
80*72b24a9dSDave Jiang                struct fwctl_rpc_cxl_out *out;
81*72b24a9dSDave Jiang                struct fwctl_rpc rpc = {0};
82*72b24a9dSDave Jiang                struct fwctl_rpc_cxl *in;
83*72b24a9dSDave Jiang                size_t out_size, in_size;
84*72b24a9dSDave Jiang                uint32_t val;
85*72b24a9dSDave Jiang                void *data;
86*72b24a9dSDave Jiang                int rc;
87*72b24a9dSDave Jiang
88*72b24a9dSDave Jiang                in_size = sizeof(*in) + sizeof(*feat_in);
89*72b24a9dSDave Jiang                rc = posix_memalign((void **)&in, 16, in_size);
90*72b24a9dSDave Jiang                if (rc)
91*72b24a9dSDave Jiang                        return -ENOMEM;
92*72b24a9dSDave Jiang                memset(in, 0, in_size);
93*72b24a9dSDave Jiang                feat_in = &in->get_feat_in;
94*72b24a9dSDave Jiang
95*72b24a9dSDave Jiang                uuid_copy(feat_in->uuid, feat_ctx->uuid);
96*72b24a9dSDave Jiang                feat_in->count = feat_ctx->get_size;
97*72b24a9dSDave Jiang
98*72b24a9dSDave Jiang                out_size = sizeof(*out) + feat_ctx->get_size;
99*72b24a9dSDave Jiang                rc = posix_memalign((void **)&out, 16, out_size);
100*72b24a9dSDave Jiang                if (rc)
101*72b24a9dSDave Jiang                        goto free_in;
102*72b24a9dSDave Jiang                memset(out, 0, out_size);
103*72b24a9dSDave Jiang
104*72b24a9dSDave Jiang                in->opcode = CXL_MBOX_OPCODE_GET_FEATURE;
105*72b24a9dSDave Jiang                in->op_size = sizeof(*feat_in);
106*72b24a9dSDave Jiang
107*72b24a9dSDave Jiang                rpc.size = sizeof(rpc);
108*72b24a9dSDave Jiang                rpc.scope = FWCTL_RPC_CONFIGURATION;
109*72b24a9dSDave Jiang                rpc.in_len = in_size;
110*72b24a9dSDave Jiang                rpc.out_len = out_size;
111*72b24a9dSDave Jiang                rpc.in = (uint64_t)(uint64_t *)in;
112*72b24a9dSDave Jiang                rpc.out = (uint64_t)(uint64_t *)out;
113*72b24a9dSDave Jiang
114*72b24a9dSDave Jiang                rc = send_command(fd, &rpc, out);
115*72b24a9dSDave Jiang                if (rc)
116*72b24a9dSDave Jiang                        goto free_all;
117*72b24a9dSDave Jiang
118*72b24a9dSDave Jiang                data = out->payload;
119*72b24a9dSDave Jiang                val = le32toh(*(__le32 *)data);
120*72b24a9dSDave Jiang                if (memcmp(&val, &expected_data, sizeof(val)) != 0) {
121*72b24a9dSDave Jiang                        rc = -ENXIO;
122*72b24a9dSDave Jiang                        goto free_all;
123*72b24a9dSDave Jiang                }
124*72b24a9dSDave Jiang
125*72b24a9dSDave Jiang        free_all:
126*72b24a9dSDave Jiang                free(out);
127*72b24a9dSDave Jiang        free_in:
128*72b24a9dSDave Jiang                free(in);
129*72b24a9dSDave Jiang                return rc;
130*72b24a9dSDave Jiang        }
131*72b24a9dSDave Jiang
132*72b24a9dSDave JiangTake a look at CXL CLI test directory
133*72b24a9dSDave Jiang<https://github.com/pmem/ndctl/tree/main/test/fwctl.c> for a detailed user code
134*72b24a9dSDave Jiangfor examples on how to exercise this path.
135*72b24a9dSDave Jiang
136*72b24a9dSDave Jiang
137*72b24a9dSDave Jiangfwctl cxl Kernel API
138*72b24a9dSDave Jiang====================
139*72b24a9dSDave Jiang
140*72b24a9dSDave Jiang.. kernel-doc:: drivers/cxl/core/features.c
141*72b24a9dSDave Jiang   :export:
142*72b24a9dSDave Jiang.. kernel-doc:: include/cxl/features.h
143