2
2
/* Copyright (c) 2020 Mellanox Technologies. All rights reserved */
3
3
4
4
#include "reg.h"
5
+ #include "core.h"
5
6
#include "spectrum.h"
6
7
#include "core_env.h"
7
8
@@ -552,6 +553,37 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
552
553
553
554
#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
554
555
556
+ struct mlxsw_sp_port_stats {
557
+ char str [ETH_GSTRING_LEN ];
558
+ u64 (* getter )(struct mlxsw_sp_port * mlxsw_sp_port );
559
+ };
560
+
561
+ static u64
562
+ mlxsw_sp_port_get_transceiver_overheat_stats (struct mlxsw_sp_port * mlxsw_sp_port )
563
+ {
564
+ struct mlxsw_sp_port_mapping port_mapping = mlxsw_sp_port -> mapping ;
565
+ struct mlxsw_core * mlxsw_core = mlxsw_sp_port -> mlxsw_sp -> core ;
566
+ u64 stats ;
567
+ int err ;
568
+
569
+ err = mlxsw_env_module_overheat_counter_get (mlxsw_core ,
570
+ port_mapping .module ,
571
+ & stats );
572
+ if (err )
573
+ return mlxsw_sp_port -> module_overheat_initial_val ;
574
+
575
+ return stats - mlxsw_sp_port -> module_overheat_initial_val ;
576
+ }
577
+
578
+ static struct mlxsw_sp_port_stats mlxsw_sp_port_transceiver_stats [] = {
579
+ {
580
+ .str = "transceiver_overheat" ,
581
+ .getter = mlxsw_sp_port_get_transceiver_overheat_stats ,
582
+ },
583
+ };
584
+
585
+ #define MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_transceiver_stats)
586
+
555
587
#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
556
588
MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \
557
589
MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
@@ -561,7 +593,8 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
561
593
(MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
562
594
IEEE_8021QAZ_MAX_TCS) + \
563
595
(MLXSW_SP_PORT_HW_TC_STATS_LEN * \
564
- TC_MAX_QUEUE))
596
+ TC_MAX_QUEUE) + \
597
+ MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN)
565
598
566
599
static void mlxsw_sp_port_get_prio_strings (u8 * * p , int prio )
567
600
{
@@ -637,6 +670,12 @@ static void mlxsw_sp_port_get_strings(struct net_device *dev,
637
670
mlxsw_sp_port_get_tc_strings (& p , i );
638
671
639
672
mlxsw_sp_port -> mlxsw_sp -> ptp_ops -> get_stats_strings (& p );
673
+
674
+ for (i = 0 ; i < MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN ; i ++ ) {
675
+ memcpy (p , mlxsw_sp_port_transceiver_stats [i ].str ,
676
+ ETH_GSTRING_LEN );
677
+ p += ETH_GSTRING_LEN ;
678
+ }
640
679
break ;
641
680
}
642
681
}
@@ -732,6 +771,17 @@ static void __mlxsw_sp_port_get_stats(struct net_device *dev,
732
771
}
733
772
}
734
773
774
+ static void __mlxsw_sp_port_get_env_stats (struct net_device * dev , u64 * data , int data_index ,
775
+ struct mlxsw_sp_port_stats * port_stats ,
776
+ int len )
777
+ {
778
+ struct mlxsw_sp_port * mlxsw_sp_port = netdev_priv (dev );
779
+ int i ;
780
+
781
+ for (i = 0 ; i < len ; i ++ )
782
+ data [data_index + i ] = port_stats [i ].getter (mlxsw_sp_port );
783
+ }
784
+
735
785
static void mlxsw_sp_port_get_stats (struct net_device * dev ,
736
786
struct ethtool_stats * stats , u64 * data )
737
787
{
@@ -786,6 +836,11 @@ static void mlxsw_sp_port_get_stats(struct net_device *dev,
786
836
mlxsw_sp_port -> mlxsw_sp -> ptp_ops -> get_stats (mlxsw_sp_port ,
787
837
data , data_index );
788
838
data_index += mlxsw_sp_port -> mlxsw_sp -> ptp_ops -> get_stats_count ();
839
+
840
+ /* Transceiver counters */
841
+ __mlxsw_sp_port_get_env_stats (dev , data , data_index , mlxsw_sp_port_transceiver_stats ,
842
+ MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN );
843
+ data_index += MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN ;
789
844
}
790
845
791
846
static int mlxsw_sp_port_get_sset_count (struct net_device * dev , int sset )
0 commit comments