101
101
#define MVNETA_TXQ_CMD 0x2448
102
102
#define MVNETA_TXQ_DISABLE_SHIFT 8
103
103
#define MVNETA_TXQ_ENABLE_MASK 0x000000ff
104
+ #define MVNETA_RX_DISCARD_FRAME_COUNT 0x2484
105
+ #define MVNETA_OVERRUN_FRAME_COUNT 0x2488
104
106
#define MVNETA_GMAC_CLOCK_DIVIDER 0x24f4
105
107
#define MVNETA_GMAC_1MS_CLOCK_ENABLE BIT(31)
106
108
#define MVNETA_ACC_MODE 0x2500
192
194
#define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11)
193
195
#define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
194
196
#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
195
- #define MVNETA_MIB_COUNTERS_BASE 0x3080
197
+ #define MVNETA_MIB_COUNTERS_BASE 0x3000
196
198
#define MVNETA_MIB_LATE_COLLISION 0x7c
197
199
#define MVNETA_DA_FILT_SPEC_MCAST 0x3400
198
200
#define MVNETA_DA_FILT_OTH_MCAST 0x3500
278
280
279
281
#define MVNETA_RX_BUF_SIZE (pkt_size ) ((pkt_size) + NET_SKB_PAD)
280
282
283
+ struct mvneta_statistic {
284
+ unsigned short offset ;
285
+ unsigned short type ;
286
+ const char name [ETH_GSTRING_LEN ];
287
+ };
288
+
289
+ #define T_REG_32 32
290
+ #define T_REG_64 64
291
+
292
+ static const struct mvneta_statistic mvneta_statistics [] = {
293
+ { 0x3000 , T_REG_64 , "good_octets_received" , },
294
+ { 0x3010 , T_REG_32 , "good_frames_received" , },
295
+ { 0x3008 , T_REG_32 , "bad_octets_received" , },
296
+ { 0x3014 , T_REG_32 , "bad_frames_received" , },
297
+ { 0x3018 , T_REG_32 , "broadcast_frames_received" , },
298
+ { 0x301c , T_REG_32 , "multicast_frames_received" , },
299
+ { 0x3050 , T_REG_32 , "unrec_mac_control_received" , },
300
+ { 0x3058 , T_REG_32 , "good_fc_received" , },
301
+ { 0x305c , T_REG_32 , "bad_fc_received" , },
302
+ { 0x3060 , T_REG_32 , "undersize_received" , },
303
+ { 0x3064 , T_REG_32 , "fragments_received" , },
304
+ { 0x3068 , T_REG_32 , "oversize_received" , },
305
+ { 0x306c , T_REG_32 , "jabber_received" , },
306
+ { 0x3070 , T_REG_32 , "mac_receive_error" , },
307
+ { 0x3074 , T_REG_32 , "bad_crc_event" , },
308
+ { 0x3078 , T_REG_32 , "collision" , },
309
+ { 0x307c , T_REG_32 , "late_collision" , },
310
+ { 0x2484 , T_REG_32 , "rx_discard" , },
311
+ { 0x2488 , T_REG_32 , "rx_overrun" , },
312
+ { 0x3020 , T_REG_32 , "frames_64_octets" , },
313
+ { 0x3024 , T_REG_32 , "frames_65_to_127_octets" , },
314
+ { 0x3028 , T_REG_32 , "frames_128_to_255_octets" , },
315
+ { 0x302c , T_REG_32 , "frames_256_to_511_octets" , },
316
+ { 0x3030 , T_REG_32 , "frames_512_to_1023_octets" , },
317
+ { 0x3034 , T_REG_32 , "frames_1024_to_max_octets" , },
318
+ { 0x3038 , T_REG_64 , "good_octets_sent" , },
319
+ { 0x3040 , T_REG_32 , "good_frames_sent" , },
320
+ { 0x3044 , T_REG_32 , "excessive_collision" , },
321
+ { 0x3048 , T_REG_32 , "multicast_frames_sent" , },
322
+ { 0x304c , T_REG_32 , "broadcast_frames_sent" , },
323
+ { 0x3054 , T_REG_32 , "fc_sent" , },
324
+ { 0x300c , T_REG_32 , "internal_mac_transmit_err" , },
325
+ };
326
+
281
327
struct mvneta_pcpu_stats {
282
328
struct u64_stats_sync syncp ;
283
329
u64 rx_packets ;
@@ -324,6 +370,8 @@ struct mvneta_port {
324
370
unsigned int speed ;
325
371
unsigned int tx_csum_limit ;
326
372
int use_inband_status :1 ;
373
+
374
+ u64 ethtool_stats [ARRAY_SIZE (mvneta_statistics )];
327
375
};
328
376
329
377
/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
@@ -530,6 +578,8 @@ static void mvneta_mib_counters_clear(struct mvneta_port *pp)
530
578
/* Perform dummy reads from MIB counters */
531
579
for (i = 0 ; i < MVNETA_MIB_LATE_COLLISION ; i += 4 )
532
580
dummy = mvreg_read (pp , (MVNETA_MIB_COUNTERS_BASE + i ));
581
+ dummy = mvreg_read (pp , MVNETA_RX_DISCARD_FRAME_COUNT );
582
+ dummy = mvreg_read (pp , MVNETA_OVERRUN_FRAME_COUNT );
533
583
}
534
584
535
585
/* Get System Network Statistics */
@@ -758,7 +808,6 @@ static void mvneta_port_up(struct mvneta_port *pp)
758
808
u32 q_map ;
759
809
760
810
/* Enable all initialized TXs. */
761
- mvneta_mib_counters_clear (pp );
762
811
q_map = 0 ;
763
812
for (queue = 0 ; queue < txq_number ; queue ++ ) {
764
813
struct mvneta_tx_queue * txq = & pp -> txqs [queue ];
@@ -1035,6 +1084,8 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
1035
1084
mvreg_write (pp , MVNETA_INTR_ENABLE ,
1036
1085
(MVNETA_RXQ_INTR_ENABLE_ALL_MASK
1037
1086
| MVNETA_TXQ_INTR_ENABLE_ALL_MASK ));
1087
+
1088
+ mvneta_mib_counters_clear (pp );
1038
1089
}
1039
1090
1040
1091
/* Set max sizes for tx queues */
@@ -2982,6 +3033,65 @@ static int mvneta_ethtool_set_ringparam(struct net_device *dev,
2982
3033
return 0 ;
2983
3034
}
2984
3035
3036
+ static void mvneta_ethtool_get_strings (struct net_device * netdev , u32 sset ,
3037
+ u8 * data )
3038
+ {
3039
+ if (sset == ETH_SS_STATS ) {
3040
+ int i ;
3041
+
3042
+ for (i = 0 ; i < ARRAY_SIZE (mvneta_statistics ); i ++ )
3043
+ memcpy (data + i * ETH_GSTRING_LEN ,
3044
+ mvneta_statistics [i ].name , ETH_GSTRING_LEN );
3045
+ }
3046
+ }
3047
+
3048
+ static void mvneta_ethtool_update_stats (struct mvneta_port * pp )
3049
+ {
3050
+ const struct mvneta_statistic * s ;
3051
+ void __iomem * base = pp -> base ;
3052
+ u32 high , low , val ;
3053
+ int i ;
3054
+
3055
+ for (i = 0 , s = mvneta_statistics ;
3056
+ s < mvneta_statistics + ARRAY_SIZE (mvneta_statistics );
3057
+ s ++ , i ++ ) {
3058
+ val = 0 ;
3059
+
3060
+ switch (s -> type ) {
3061
+ case T_REG_32 :
3062
+ val = readl_relaxed (base + s -> offset );
3063
+ break ;
3064
+ case T_REG_64 :
3065
+ /* Docs say to read low 32-bit then high */
3066
+ low = readl_relaxed (base + s -> offset );
3067
+ high = readl_relaxed (base + s -> offset + 4 );
3068
+ val = (u64 )high << 32 | low ;
3069
+ break ;
3070
+ }
3071
+
3072
+ pp -> ethtool_stats [i ] += val ;
3073
+ }
3074
+ }
3075
+
3076
+ static void mvneta_ethtool_get_stats (struct net_device * dev ,
3077
+ struct ethtool_stats * stats , u64 * data )
3078
+ {
3079
+ struct mvneta_port * pp = netdev_priv (dev );
3080
+ int i ;
3081
+
3082
+ mvneta_ethtool_update_stats (pp );
3083
+
3084
+ for (i = 0 ; i < ARRAY_SIZE (mvneta_statistics ); i ++ )
3085
+ * data ++ = pp -> ethtool_stats [i ];
3086
+ }
3087
+
3088
+ static int mvneta_ethtool_get_sset_count (struct net_device * dev , int sset )
3089
+ {
3090
+ if (sset == ETH_SS_STATS )
3091
+ return ARRAY_SIZE (mvneta_statistics );
3092
+ return - EOPNOTSUPP ;
3093
+ }
3094
+
2985
3095
static const struct net_device_ops mvneta_netdev_ops = {
2986
3096
.ndo_open = mvneta_open ,
2987
3097
.ndo_stop = mvneta_stop ,
@@ -3003,6 +3113,9 @@ const struct ethtool_ops mvneta_eth_tool_ops = {
3003
3113
.get_drvinfo = mvneta_ethtool_get_drvinfo ,
3004
3114
.get_ringparam = mvneta_ethtool_get_ringparam ,
3005
3115
.set_ringparam = mvneta_ethtool_set_ringparam ,
3116
+ .get_strings = mvneta_ethtool_get_strings ,
3117
+ .get_ethtool_stats = mvneta_ethtool_get_stats ,
3118
+ .get_sset_count = mvneta_ethtool_get_sset_count ,
3006
3119
};
3007
3120
3008
3121
/* Initialize hw */
0 commit comments