fwctl cxl driver

Author:

Dave Jiang

Overview

The CXL spec defines a set of commands that can be issued to the mailbox of aCXL device or switch. It also left room for vendor specific commands to beissued to the mailbox as well. fwctl provides a path to issue a set of allowedmailbox commands from user space to the device moderated by the kernel driver.

The following 3 commands will be used to support CXL Features:CXL spec r3.1 8.2.9.6.1 Get Supported Features (Opcode 0500h)CXL spec r3.1 8.2.9.6.2 Get Feature (Opcode 0501h)CXL spec r3.1 8.2.9.6.3 Set Feature (Opcode 0502h)

The “Get Supported Features” return data may be filtered by the kernel driver todrop any features that are forbidden by the kernel or being exclusively used bythe kernel. The driver will set the “Set Feature Size” of the “Get SupportedFeatures Supported Feature Entry” to 0 to indicate that the Feature cannot bemodified. The “Get Supported Features” command and the “Get Features” fallsunder the fwctl policy of FWCTL_RPC_CONFIGURATION.

For “Set Feature” command, the access policy currently is broken down into twocategories depending on the Set Feature effects reported by the device. If theSet Feature will cause immediate change to the device, the fwctl access policymust be FWCTL_RPC_DEBUG_WRITE_FULL. The effects for this level are“immediate config change”, “immediate data change”, “immediate policy change”,or “immediate log change” for the set effects mask. If the effects are “configchange with cold reset” or “config change with conventional reset”, then thefwctl access policy must be FWCTL_RPC_DEBUG_WRITE or higher.

fwctl cxl User API

structfwctl_rpc_cxl

ioctl(FWCTL_RPC) input for CXL

Definition:

struct fwctl_rpc_cxl {    __u32 opcode;    __u32 flags;    __u32 op_size;    __u32 reserved1;    union {        struct cxl_mbox_get_sup_feats_in get_sup_feats_in;        struct cxl_mbox_get_feat_in get_feat_in;        struct cxl_mbox_set_feat_in set_feat_in;    };};

Members

opcode

CXL mailbox command opcode

flags

Flags for the command (input).

op_size

Size of input payload.

reserved1

Reserved. Must be 0s.

{unnamed_union}

anonymous

get_sup_feats_in

Get Supported Features input

get_feat_in

Get Feature input

set_feat_in

Set Feature input

structfwctl_rpc_cxl_out

ioctl(FWCTL_RPC) output for CXL

Definition:

struct fwctl_rpc_cxl_out {    __u32 size;    __u32 retval;    union {        struct cxl_mbox_get_sup_feats_out get_sup_feats_out;        __u8 payload[];    };};

Members

size

Size of the output payload

retval

Return value from device

{unnamed_union}

anonymous

get_sup_feats_out

Get Supported Features output

payload

raw byte stream of payload

1. Driver info query

First step for the app is to issue the ioctl(FWCTL_CMD_INFO). Successfulinvocation of the ioctl implies the Features capability is operational andreturns an all zeros 32bit payload. Astructfwctl_info needs to be filledout with thefwctl_info.out_device_type set toFWCTL_DEVICE_TYPE_CXL.The return data should bestructfwctl_info_cxl that contains a reserved32bit field that should be all zeros.

2. Send hardware commands

Next step is to send the ‘Get Supported Features’ command to the driver fromuser space via ioctl(FWCTL_RPC). Astructfwctl_rpc_cxl is pointed tobyfwctl_rpc.in.structfwctl_rpc_cxl.in_payload points tothe hardware input structure that is defined by the CXL spec.fwctl_rpc.outpoints to the buffer that contains astructfwctl_rpc_cxl_out that includesthe hardware output data inlined asfwctl_rpc_cxl_out.payload. This commandis called twice. First time to retrieve the number of features supported.A second time to retrieve the specific feature details as the output data.

After getting the specific feature details, a Get/Set Feature command can beappropriately programmed and sent. For a “Set Feature” command, the retrievedfeature info contains an effects field that details the resulting“Set Feature” command will trigger. That will inform the user whetherthe system is configured to allowed the “Set Feature” command or not.

Code example of a Get Feature

staticintcxl_fwctl_rpc_get_test_feature(intfd,structtest_feature*feat_ctx,constuint32_texpected_data){structcxl_mbox_get_feat_in*feat_in;structfwctl_rpc_cxl_out*out;structfwctl_rpcrpc={0};structfwctl_rpc_cxl*in;size_tout_size,in_size;uint32_tval;void*data;intrc;in_size=sizeof(*in)+sizeof(*feat_in);rc=posix_memalign((void**)&in,16,in_size);if(rc)return-ENOMEM;memset(in,0,in_size);feat_in=&in->get_feat_in;uuid_copy(feat_in->uuid,feat_ctx->uuid);feat_in->count=feat_ctx->get_size;out_size=sizeof(*out)+feat_ctx->get_size;rc=posix_memalign((void**)&out,16,out_size);if(rc)gotofree_in;memset(out,0,out_size);in->opcode=CXL_MBOX_OPCODE_GET_FEATURE;in->op_size=sizeof(*feat_in);rpc.size=sizeof(rpc);rpc.scope=FWCTL_RPC_CONFIGURATION;rpc.in_len=in_size;rpc.out_len=out_size;rpc.in=(uint64_t)(uint64_t*)in;rpc.out=(uint64_t)(uint64_t*)out;rc=send_command(fd,&rpc,out);if(rc)gotofree_all;data=out->payload;val=le32toh(*(__le32*)data);if(memcmp(&val,&expected_data,sizeof(val))!=0){rc=-ENXIO;gotofree_all;}free_all:free(out);free_in:free(in);returnrc;}

Take a look at CXL CLI test directory<https://github.com/pmem/ndctl/tree/main/test/fwctl.c> for a detailed user codefor examples on how to exercise this path.

fwctl cxl Kernel API

intdevm_cxl_setup_features(structcxl_dev_state*cxlds)

Allocate and initialize features context

Parameters

structcxl_dev_state*cxlds

CXL device context

Description

Return 0 on success or -errno on failure.

structcxl_features_state

The Features state for the device

Definition:

struct cxl_features_state {    struct cxl_dev_state *cxlds;    struct cxl_feat_entries {        int num_features;        int num_user_features;        struct cxl_feat_entry ent[] ;    } *entries;};

Members

cxlds

Pointer to CXL device state

entries

CXl feature entry context