@@ -507,6 +507,119 @@ int do_security_info(nvme_mi_ep_t ep, int argc, char **argv)
507507 return 0 ;
508508}
509509
510+ struct {
511+ enum nvme_mi_config_smbus_freq id ;
512+ const char * str ;
513+ } smbus_freqs [] = {
514+ { NVME_MI_CONFIG_SMBUS_FREQ_100kHz , "100k" },
515+ { NVME_MI_CONFIG_SMBUS_FREQ_400kHz , "400k" },
516+ { NVME_MI_CONFIG_SMBUS_FREQ_1MHz , "1M" },
517+ };
518+
519+ static const char * smbus_freq_str (enum nvme_mi_config_smbus_freq freq )
520+ {
521+ unsigned int i ;
522+
523+ for (i = 0 ; i < ARRAY_SIZE (smbus_freqs ); i ++ ) {
524+ if (smbus_freqs [i ].id == freq )
525+ return smbus_freqs [i ].str ;
526+ }
527+
528+ return NULL ;
529+ }
530+
531+ static int smbus_freq_val (const char * str , enum nvme_mi_config_smbus_freq * freq )
532+ {
533+ unsigned int i ;
534+
535+ for (i = 0 ; i < ARRAY_SIZE (smbus_freqs ); i ++ ) {
536+ if (!strcmp (smbus_freqs [i ].str , str )) {
537+ * freq = smbus_freqs [i ].id ;
538+ return 0 ;
539+ }
540+ }
541+
542+ return -1 ;
543+ }
544+
545+ int do_config_get (nvme_mi_ep_t ep , int argc , char * * argv )
546+ {
547+ enum nvme_mi_config_smbus_freq freq ;
548+ uint16_t mtu ;
549+ uint8_t port ;
550+ int rc ;
551+
552+ if (argc > 1 )
553+ port = atoi (argv [1 ]) & 0xff ;
554+ else
555+ port = 0 ;
556+
557+ rc = nvme_mi_mi_config_get_smbus_freq (ep , port , & freq );
558+ if (rc ) {
559+ warn ("can't query SMBus freq for port %d\n" , port );
560+ } else {
561+ const char * fstr = smbus_freq_str (freq );
562+ printf ("SMBus access frequency (port %d): %s [0x%x]\n" , port ,
563+ fstr ?: "unknown" , freq );
564+ }
565+
566+ rc = nvme_mi_mi_config_get_mctp_mtu (ep , port , & mtu );
567+ if (rc )
568+ warn ("can't query MCTP MTU for port %d\n" , port );
569+ else
570+ printf ("MCTP MTU (port %d): %d\n" , port , mtu );
571+
572+ return 0 ;
573+ }
574+
575+ int do_config_set (nvme_mi_ep_t ep , int argc , char * * argv )
576+ {
577+ const char * name , * val ;
578+ uint8_t port ;
579+ int rc ;
580+
581+ if (argc != 4 ) {
582+ fprintf (stderr , "config set requires <port> <type> <val>\n" );
583+ return -1 ;
584+ }
585+
586+ port = atoi (argv [1 ]) & 0xff ;
587+ name = argv [2 ];
588+ val = argv [3 ];
589+
590+ if (!strcmp (name , "freq" )) {
591+ enum nvme_mi_config_smbus_freq freq ;
592+ rc = smbus_freq_val (val , & freq );
593+ if (rc ) {
594+ fprintf (stderr , "unknown SMBus freq %s. "
595+ "Try 100k, 400k or 1M\n" , val );
596+ return -1 ;
597+ }
598+ rc = nvme_mi_mi_config_set_smbus_freq (ep , port , freq );
599+
600+ } else if (!strcmp (name , "mtu" )) {
601+ uint16_t mtu ;
602+ mtu = atoi (val ) & 0xffff ;
603+ /* controllers should reject this, but prevent the potential
604+ * footgun of disabling futher comunication with the device
605+ */
606+ if (mtu < 64 ) {
607+ fprintf (stderr , "MTU value too small\n" );
608+ return -1 ;
609+ }
610+ rc = nvme_mi_mi_config_set_mctp_mtu (ep , port , mtu );
611+
612+ } else {
613+ fprintf (stderr , "Invalid configuration '%s', "
614+ "try freq or mtu\n" , name );
615+ return -1 ;
616+ }
617+
618+ if (rc )
619+ fprintf (stderr , "config set failed with status %d\n" , rc );
620+
621+ return rc ;
622+ }
510623
511624enum action {
512625 ACTION_INFO ,
@@ -515,6 +628,8 @@ enum action {
515628 ACTION_GET_LOG_PAGE ,
516629 ACTION_ADMIN_RAW ,
517630 ACTION_SECURITY_INFO ,
631+ ACTION_CONFIG_GET ,
632+ ACTION_CONFIG_SET ,
518633};
519634
520635static int do_action_endpoint (enum action action , nvme_mi_ep_t ep , int argc , char * * argv )
@@ -540,6 +655,12 @@ static int do_action_endpoint(enum action action, nvme_mi_ep_t ep, int argc, cha
540655 case ACTION_SECURITY_INFO :
541656 rc = do_security_info (ep , argc , argv );
542657 break ;
658+ case ACTION_CONFIG_GET :
659+ rc = do_config_get (ep , argc , argv );
660+ break ;
661+ case ACTION_CONFIG_SET :
662+ rc = do_config_set (ep , argc , argv );
663+ break ;
543664 }
544665 return rc ;
545666}
@@ -578,6 +699,8 @@ int main(int argc, char **argv)
578699 " get-log-page <controller-id> [<log-id>]\n"
579700 " admin <controller-id> <opcode> [<cdw10>, <cdw11>, ...]\n"
580701 " security-info <controller-id>\n"
702+ " get-config [port]\n"
703+ " set-config <port> <type> <val>\n"
581704 "\n"
582705 " 'dbus' target will query D-Bus for known MCTP endpoints\n"
583706 );
@@ -603,6 +726,10 @@ int main(int argc, char **argv)
603726 action = ACTION_ADMIN_RAW ;
604727 } else if (!strcmp (action_str , "security-info" )) {
605728 action = ACTION_SECURITY_INFO ;
729+ } else if (!strcmp (action_str , "get-config" )) {
730+ action = ACTION_CONFIG_GET ;
731+ } else if (!strcmp (action_str , "set-config" )) {
732+ action = ACTION_CONFIG_SET ;
606733 } else {
607734 fprintf (stderr , "invalid action '%s'\n" , action_str );
608735 return EXIT_FAILURE ;
0 commit comments