37
37
#include "mlx5_core.h"
38
38
#include "../../mlxfw/mlxfw.h"
39
39
40
+ enum {
41
+ MCQS_IDENTIFIER_BOOT_IMG = 0x1 ,
42
+ MCQS_IDENTIFIER_OEM_NVCONFIG = 0x4 ,
43
+ MCQS_IDENTIFIER_MLNX_NVCONFIG = 0x5 ,
44
+ MCQS_IDENTIFIER_CS_TOKEN = 0x6 ,
45
+ MCQS_IDENTIFIER_DBG_TOKEN = 0x7 ,
46
+ MCQS_IDENTIFIER_GEARBOX = 0xA ,
47
+ };
48
+
49
+ enum {
50
+ MCQS_UPDATE_STATE_IDLE ,
51
+ MCQS_UPDATE_STATE_IN_PROGRESS ,
52
+ MCQS_UPDATE_STATE_APPLIED ,
53
+ MCQS_UPDATE_STATE_ACTIVE ,
54
+ MCQS_UPDATE_STATE_ACTIVE_PENDING_RESET ,
55
+ MCQS_UPDATE_STATE_FAILED ,
56
+ MCQS_UPDATE_STATE_CANCELED ,
57
+ MCQS_UPDATE_STATE_BUSY ,
58
+ };
59
+
60
+ enum {
61
+ MCQI_INFO_TYPE_CAPABILITIES = 0x0 ,
62
+ MCQI_INFO_TYPE_VERSION = 0x1 ,
63
+ MCQI_INFO_TYPE_ACTIVATION_METHOD = 0x5 ,
64
+ };
65
+
66
+ enum {
67
+ MCQI_FW_RUNNING_VERSION = 0 ,
68
+ MCQI_FW_STORED_VERSION = 1 ,
69
+ };
70
+
40
71
static int mlx5_cmd_query_adapter (struct mlx5_core_dev * dev , u32 * out ,
41
72
int outlen )
42
73
{
@@ -398,33 +429,49 @@ static int mlx5_reg_mcda_set(struct mlx5_core_dev *dev,
398
429
}
399
430
400
431
static int mlx5_reg_mcqi_query (struct mlx5_core_dev * dev ,
401
- u16 component_index ,
402
- u32 * max_component_size ,
403
- u8 * log_mcda_word_size ,
404
- u16 * mcda_max_write_size )
432
+ u16 component_index , bool read_pending ,
433
+ u8 info_type , u16 data_size , void * mcqi_data )
405
434
{
406
- u32 out [MLX5_ST_SZ_DW (mcqi_reg ) + MLX5_ST_SZ_DW ( mcqi_cap )] ;
407
- int offset = MLX5_ST_SZ_DW (mcqi_reg );
408
- u32 in [ MLX5_ST_SZ_DW ( mcqi_reg )] ;
435
+ u32 out [MLX5_ST_SZ_DW (mcqi_reg ) + MLX5_UN_SZ_DW ( mcqi_reg_data )] = {} ;
436
+ u32 in [ MLX5_ST_SZ_DW (mcqi_reg )] = {} ;
437
+ void * data ;
409
438
int err ;
410
439
411
- memset (in , 0 , sizeof (in ));
412
- memset (out , 0 , sizeof (out ));
413
-
414
440
MLX5_SET (mcqi_reg , in , component_index , component_index );
415
- MLX5_SET (mcqi_reg , in , data_size , MLX5_ST_SZ_BYTES (mcqi_cap ));
441
+ MLX5_SET (mcqi_reg , in , read_pending_component , read_pending );
442
+ MLX5_SET (mcqi_reg , in , info_type , info_type );
443
+ MLX5_SET (mcqi_reg , in , data_size , data_size );
416
444
417
445
err = mlx5_core_access_reg (dev , in , sizeof (in ), out ,
418
- sizeof (out ), MLX5_REG_MCQI , 0 , 0 );
446
+ MLX5_ST_SZ_BYTES (mcqi_reg ) + data_size ,
447
+ MLX5_REG_MCQI , 0 , 0 );
419
448
if (err )
420
- goto out ;
449
+ return err ;
421
450
422
- * max_component_size = MLX5_GET (mcqi_cap , out + offset , max_component_size );
423
- * log_mcda_word_size = MLX5_GET (mcqi_cap , out + offset , log_mcda_word_size );
424
- * mcda_max_write_size = MLX5_GET (mcqi_cap , out + offset , mcda_max_write_size );
451
+ data = MLX5_ADDR_OF (mcqi_reg , out , data );
452
+ memcpy (mcqi_data , data , data_size );
425
453
426
- out :
427
- return err ;
454
+ return 0 ;
455
+ }
456
+
457
+ static int mlx5_reg_mcqi_caps_query (struct mlx5_core_dev * dev , u16 component_index ,
458
+ u32 * max_component_size , u8 * log_mcda_word_size ,
459
+ u16 * mcda_max_write_size )
460
+ {
461
+ u32 mcqi_reg [MLX5_ST_SZ_DW (mcqi_cap )] = {};
462
+ int err ;
463
+
464
+ err = mlx5_reg_mcqi_query (dev , component_index , 0 ,
465
+ MCQI_INFO_TYPE_CAPABILITIES ,
466
+ MLX5_ST_SZ_BYTES (mcqi_cap ), mcqi_reg );
467
+ if (err )
468
+ return err ;
469
+
470
+ * max_component_size = MLX5_GET (mcqi_cap , mcqi_reg , max_component_size );
471
+ * log_mcda_word_size = MLX5_GET (mcqi_cap , mcqi_reg , log_mcda_word_size );
472
+ * mcda_max_write_size = MLX5_GET (mcqi_cap , mcqi_reg , mcda_max_write_size );
473
+
474
+ return 0 ;
428
475
}
429
476
430
477
struct mlx5_mlxfw_dev {
@@ -440,8 +487,13 @@ static int mlx5_component_query(struct mlxfw_dev *mlxfw_dev,
440
487
container_of (mlxfw_dev , struct mlx5_mlxfw_dev , mlxfw_dev );
441
488
struct mlx5_core_dev * dev = mlx5_mlxfw_dev -> mlx5_core_dev ;
442
489
443
- return mlx5_reg_mcqi_query (dev , component_index , p_max_size ,
444
- p_align_bits , p_max_write_size );
490
+ if (!MLX5_CAP_GEN (dev , mcam_reg ) || !MLX5_CAP_MCAM_REG (dev , mcqi )) {
491
+ mlx5_core_warn (dev , "caps query isn't supported by running FW\n" );
492
+ return - EOPNOTSUPP ;
493
+ }
494
+
495
+ return mlx5_reg_mcqi_caps_query (dev , component_index , p_max_size ,
496
+ p_align_bits , p_max_write_size );
445
497
}
446
498
447
499
static int mlx5_fsm_lock (struct mlxfw_dev * mlxfw_dev , u32 * fwhandle )
@@ -581,3 +633,130 @@ int mlx5_firmware_flash(struct mlx5_core_dev *dev,
581
633
return mlxfw_firmware_flash (& mlx5_mlxfw_dev .mlxfw_dev ,
582
634
firmware , extack );
583
635
}
636
+
637
+ static int mlx5_reg_mcqi_version_query (struct mlx5_core_dev * dev ,
638
+ u16 component_index , bool read_pending ,
639
+ u32 * mcqi_version_out )
640
+ {
641
+ return mlx5_reg_mcqi_query (dev , component_index , read_pending ,
642
+ MCQI_INFO_TYPE_VERSION ,
643
+ MLX5_ST_SZ_BYTES (mcqi_version ),
644
+ mcqi_version_out );
645
+ }
646
+
647
+ static int mlx5_reg_mcqs_query (struct mlx5_core_dev * dev , u32 * out ,
648
+ u16 component_index )
649
+ {
650
+ u8 out_sz = MLX5_ST_SZ_BYTES (mcqs_reg );
651
+ u32 in [MLX5_ST_SZ_DW (mcqs_reg )] = {};
652
+ int err ;
653
+
654
+ memset (out , 0 , out_sz );
655
+
656
+ MLX5_SET (mcqs_reg , in , component_index , component_index );
657
+
658
+ err = mlx5_core_access_reg (dev , in , sizeof (in ), out ,
659
+ out_sz , MLX5_REG_MCQS , 0 , 0 );
660
+ return err ;
661
+ }
662
+
663
+ /* scans component index sequentially, to find the boot img index */
664
+ static int mlx5_get_boot_img_component_index (struct mlx5_core_dev * dev )
665
+ {
666
+ u32 out [MLX5_ST_SZ_DW (mcqs_reg )] = {};
667
+ u16 identifier , component_idx = 0 ;
668
+ bool quit ;
669
+ int err ;
670
+
671
+ do {
672
+ err = mlx5_reg_mcqs_query (dev , out , component_idx );
673
+ if (err )
674
+ return err ;
675
+
676
+ identifier = MLX5_GET (mcqs_reg , out , identifier );
677
+ quit = !!MLX5_GET (mcqs_reg , out , last_index_flag );
678
+ quit |= identifier == MCQS_IDENTIFIER_BOOT_IMG ;
679
+ } while (!quit && ++ component_idx );
680
+
681
+ if (identifier != MCQS_IDENTIFIER_BOOT_IMG ) {
682
+ mlx5_core_warn (dev , "mcqs: can't find boot_img component ix, last scanned idx %d\n" ,
683
+ component_idx );
684
+ return - EOPNOTSUPP ;
685
+ }
686
+
687
+ return component_idx ;
688
+ }
689
+
690
+ static int
691
+ mlx5_fw_image_pending (struct mlx5_core_dev * dev ,
692
+ int component_index ,
693
+ bool * pending_version_exists )
694
+ {
695
+ u32 out [MLX5_ST_SZ_DW (mcqs_reg )];
696
+ u8 component_update_state ;
697
+ int err ;
698
+
699
+ err = mlx5_reg_mcqs_query (dev , out , component_index );
700
+ if (err )
701
+ return err ;
702
+
703
+ component_update_state = MLX5_GET (mcqs_reg , out , component_update_state );
704
+
705
+ if (component_update_state == MCQS_UPDATE_STATE_IDLE ) {
706
+ * pending_version_exists = false;
707
+ } else if (component_update_state == MCQS_UPDATE_STATE_ACTIVE_PENDING_RESET ) {
708
+ * pending_version_exists = true;
709
+ } else {
710
+ mlx5_core_warn (dev ,
711
+ "mcqs: can't read pending fw version while fw state is %d\n" ,
712
+ component_update_state );
713
+ return - ENODATA ;
714
+ }
715
+ return 0 ;
716
+ }
717
+
718
+ int mlx5_fw_version_query (struct mlx5_core_dev * dev ,
719
+ u32 * running_ver , u32 * pending_ver )
720
+ {
721
+ u32 reg_mcqi_version [MLX5_ST_SZ_DW (mcqi_version )] = {};
722
+ bool pending_version_exists ;
723
+ int component_index ;
724
+ int err ;
725
+
726
+ if (!MLX5_CAP_GEN (dev , mcam_reg ) || !MLX5_CAP_MCAM_REG (dev , mcqi ) ||
727
+ !MLX5_CAP_MCAM_REG (dev , mcqs )) {
728
+ mlx5_core_warn (dev , "fw query isn't supported by the FW\n" );
729
+ return - EOPNOTSUPP ;
730
+ }
731
+
732
+ component_index = mlx5_get_boot_img_component_index (dev );
733
+ if (component_index < 0 )
734
+ return component_index ;
735
+
736
+ err = mlx5_reg_mcqi_version_query (dev , component_index ,
737
+ MCQI_FW_RUNNING_VERSION ,
738
+ reg_mcqi_version );
739
+ if (err )
740
+ return err ;
741
+
742
+ * running_ver = MLX5_GET (mcqi_version , reg_mcqi_version , version );
743
+
744
+ err = mlx5_fw_image_pending (dev , component_index , & pending_version_exists );
745
+ if (err )
746
+ return err ;
747
+
748
+ if (!pending_version_exists ) {
749
+ * pending_ver = 0 ;
750
+ return 0 ;
751
+ }
752
+
753
+ err = mlx5_reg_mcqi_version_query (dev , component_index ,
754
+ MCQI_FW_STORED_VERSION ,
755
+ reg_mcqi_version );
756
+ if (err )
757
+ return err ;
758
+
759
+ * pending_ver = MLX5_GET (mcqi_version , reg_mcqi_version , version );
760
+
761
+ return 0 ;
762
+ }
0 commit comments