Skip to content

Commit 14d502c

Browse files
shijujose4davejiang
authored andcommitted
cxl/mbox: Add SET_FEATURE mailbox command
Add support for SET_FEATURE mailbox command. CXL spec r3.2 section 8.2.9.6 describes optional device specific features. CXL devices supports features with changeable attributes. The settings of a feature can be optionally modified using Set Feature command. CXL spec r3.2 section 8.2.9.6.3 describes Set Feature command. 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: Shiju Jose <shiju.jose@huawei.com> Link: https://patch.msgid.link/20250220194438.2281088-6-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 5e5ac21 commit 14d502c

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

drivers/cxl/core/core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ size_t cxl_get_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
122122
enum cxl_get_feat_selection selection,
123123
void *feat_out, size_t feat_out_size, u16 offset,
124124
u16 *return_code);
125+
int cxl_set_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
126+
u8 feat_version, const void *feat_data,
127+
size_t feat_data_size, u32 feat_flag, u16 offset,
128+
u16 *return_code);
125129
#endif
126130

127131
#endif /* __CXL_CORE_H__ */

drivers/cxl/core/features.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,83 @@ size_t cxl_get_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
223223

224224
return data_rcvd_size;
225225
}
226+
227+
/*
228+
* FEAT_DATA_MIN_PAYLOAD_SIZE - min extra number of bytes should be
229+
* available in the mailbox for storing the actual feature data so that
230+
* the feature data transfer would work as expected.
231+
*/
232+
#define FEAT_DATA_MIN_PAYLOAD_SIZE 10
233+
int cxl_set_feature(struct cxl_mailbox *cxl_mbox,
234+
const uuid_t *feat_uuid, u8 feat_version,
235+
const void *feat_data, size_t feat_data_size,
236+
u32 feat_flag, u16 offset, u16 *return_code)
237+
{
238+
size_t data_in_size, data_sent_size = 0;
239+
struct cxl_mbox_cmd mbox_cmd;
240+
size_t hdr_size;
241+
242+
if (return_code)
243+
*return_code = CXL_MBOX_CMD_RC_INPUT;
244+
245+
struct cxl_mbox_set_feat_in *pi __free(kfree) =
246+
kzalloc(cxl_mbox->payload_size, GFP_KERNEL);
247+
if (!pi)
248+
return -ENOMEM;
249+
250+
uuid_copy(&pi->uuid, feat_uuid);
251+
pi->version = feat_version;
252+
feat_flag &= ~CXL_SET_FEAT_FLAG_DATA_TRANSFER_MASK;
253+
feat_flag |= CXL_SET_FEAT_FLAG_DATA_SAVED_ACROSS_RESET;
254+
hdr_size = sizeof(pi->hdr);
255+
/*
256+
* Check minimum mbox payload size is available for
257+
* the feature data transfer.
258+
*/
259+
if (hdr_size + FEAT_DATA_MIN_PAYLOAD_SIZE > cxl_mbox->payload_size)
260+
return -ENOMEM;
261+
262+
if (hdr_size + feat_data_size <= cxl_mbox->payload_size) {
263+
pi->flags = cpu_to_le32(feat_flag |
264+
CXL_SET_FEAT_FLAG_FULL_DATA_TRANSFER);
265+
data_in_size = feat_data_size;
266+
} else {
267+
pi->flags = cpu_to_le32(feat_flag |
268+
CXL_SET_FEAT_FLAG_INITIATE_DATA_TRANSFER);
269+
data_in_size = cxl_mbox->payload_size - hdr_size;
270+
}
271+
272+
do {
273+
int rc;
274+
275+
pi->offset = cpu_to_le16(offset + data_sent_size);
276+
memcpy(pi->feat_data, feat_data + data_sent_size, data_in_size);
277+
mbox_cmd = (struct cxl_mbox_cmd) {
278+
.opcode = CXL_MBOX_OP_SET_FEATURE,
279+
.size_in = hdr_size + data_in_size,
280+
.payload_in = pi,
281+
};
282+
rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
283+
if (rc < 0) {
284+
if (return_code)
285+
*return_code = mbox_cmd.return_code;
286+
return rc;
287+
}
288+
289+
data_sent_size += data_in_size;
290+
if (data_sent_size >= feat_data_size) {
291+
if (return_code)
292+
*return_code = CXL_MBOX_CMD_RC_SUCCESS;
293+
return 0;
294+
}
295+
296+
if ((feat_data_size - data_sent_size) <= (cxl_mbox->payload_size - hdr_size)) {
297+
data_in_size = feat_data_size - data_sent_size;
298+
pi->flags = cpu_to_le32(feat_flag |
299+
CXL_SET_FEAT_FLAG_FINISH_DATA_TRANSFER);
300+
} else {
301+
pi->flags = cpu_to_le32(feat_flag |
302+
CXL_SET_FEAT_FLAG_CONTINUE_DATA_TRANSFER);
303+
}
304+
} while (true);
305+
}

include/cxl/features.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,39 @@ enum cxl_get_feat_selection {
9090
CXL_GET_FEAT_SEL_MAX
9191
};
9292

93+
/*
94+
* Set Feature CXL spec r3.2 8.2.9.6.3
95+
*/
96+
97+
/*
98+
* Set Feature input payload
99+
* CXL spec r3.2 section 8.2.9.6.3 Table 8-101
100+
*/
101+
struct cxl_mbox_set_feat_in {
102+
__struct_group(cxl_mbox_set_feat_hdr, hdr, /* no attrs */,
103+
uuid_t uuid;
104+
__le32 flags;
105+
__le16 offset;
106+
u8 version;
107+
u8 rsvd[9];
108+
);
109+
__u8 feat_data[];
110+
} __packed;
111+
112+
/* Set Feature flags field */
113+
enum cxl_set_feat_flag_data_transfer {
114+
CXL_SET_FEAT_FLAG_FULL_DATA_TRANSFER = 0,
115+
CXL_SET_FEAT_FLAG_INITIATE_DATA_TRANSFER,
116+
CXL_SET_FEAT_FLAG_CONTINUE_DATA_TRANSFER,
117+
CXL_SET_FEAT_FLAG_FINISH_DATA_TRANSFER,
118+
CXL_SET_FEAT_FLAG_ABORT_DATA_TRANSFER,
119+
CXL_SET_FEAT_FLAG_DATA_TRANSFER_MAX
120+
};
121+
122+
#define CXL_SET_FEAT_FLAG_DATA_TRANSFER_MASK GENMASK(2, 0)
123+
124+
#define CXL_SET_FEAT_FLAG_DATA_SAVED_ACROSS_RESET BIT(3)
125+
93126
/**
94127
* struct cxl_features_state - The Features state for the device
95128
* @cxlds: Pointer to CXL device state

0 commit comments

Comments
 (0)