@@ -427,6 +427,47 @@ static void *cxlctl_get_supported_features(struct cxl_features_state *cxlfs,
427
427
return no_free_ptr (rpc_out );
428
428
}
429
429
430
+ static void * cxlctl_get_feature (struct cxl_features_state * cxlfs ,
431
+ const struct fwctl_rpc_cxl * rpc_in ,
432
+ size_t * out_len )
433
+ {
434
+ struct cxl_mailbox * cxl_mbox = & cxlfs -> cxlds -> cxl_mbox ;
435
+ const struct cxl_mbox_get_feat_in * feat_in ;
436
+ u16 offset , count , return_code ;
437
+ size_t out_size = * out_len ;
438
+
439
+ if (rpc_in -> op_size != sizeof (* feat_in ))
440
+ return ERR_PTR (- EINVAL );
441
+
442
+ feat_in = & rpc_in -> get_feat_in ;
443
+ offset = le16_to_cpu (feat_in -> offset );
444
+ count = le16_to_cpu (feat_in -> count );
445
+
446
+ if (!count )
447
+ return ERR_PTR (- EINVAL );
448
+
449
+ struct fwctl_rpc_cxl_out * rpc_out __free (kvfree ) =
450
+ kvzalloc (out_size , GFP_KERNEL );
451
+ if (!rpc_out )
452
+ return ERR_PTR (- ENOMEM );
453
+
454
+ out_size = cxl_get_feature (cxl_mbox , & feat_in -> uuid ,
455
+ feat_in -> selection , rpc_out -> payload ,
456
+ count , offset , & return_code );
457
+ * out_len = sizeof (struct fwctl_rpc_cxl_out );
458
+ if (!out_size ) {
459
+ rpc_out -> size = 0 ;
460
+ rpc_out -> retval = return_code ;
461
+ return no_free_ptr (rpc_out );
462
+ }
463
+
464
+ rpc_out -> size = out_size ;
465
+ rpc_out -> retval = CXL_MBOX_CMD_RC_SUCCESS ;
466
+ * out_len += out_size ;
467
+
468
+ return no_free_ptr (rpc_out );
469
+ }
470
+
430
471
static bool cxlctl_validate_hw_command (struct cxl_features_state * cxlfs ,
431
472
const struct fwctl_rpc_cxl * rpc_in ,
432
473
enum fwctl_rpc_scope scope ,
@@ -436,6 +477,7 @@ static bool cxlctl_validate_hw_command(struct cxl_features_state *cxlfs,
436
477
437
478
switch (opcode ) {
438
479
case CXL_MBOX_OP_GET_SUPPORTED_FEATURES :
480
+ case CXL_MBOX_OP_GET_FEATURE :
439
481
if (cxl_mbox -> feat_cap < CXL_FEATURES_RO )
440
482
return false;
441
483
if (scope >= FWCTL_RPC_CONFIGURATION )
@@ -453,6 +495,8 @@ static void *cxlctl_handle_commands(struct cxl_features_state *cxlfs,
453
495
switch (opcode ) {
454
496
case CXL_MBOX_OP_GET_SUPPORTED_FEATURES :
455
497
return cxlctl_get_supported_features (cxlfs , rpc_in , out_len );
498
+ case CXL_MBOX_OP_GET_FEATURE :
499
+ return cxlctl_get_feature (cxlfs , rpc_in , out_len );
456
500
default :
457
501
return ERR_PTR (- EOPNOTSUPP );
458
502
}
0 commit comments