@@ -642,6 +642,7 @@ struct gbe_priv {
642
642
bool enable_ale ;
643
643
u8 max_num_slaves ;
644
644
u8 max_num_ports ; /* max_num_slaves + 1 */
645
+ u8 num_stats_mods ;
645
646
struct netcp_tx_pipe tx_pipe ;
646
647
647
648
int host_port ;
@@ -671,6 +672,7 @@ struct gbe_priv {
671
672
struct net_device * dummy_ndev ;
672
673
673
674
u64 * hw_stats ;
675
+ u32 * hw_stats_prev ;
674
676
const struct netcp_ethtool_stat * et_stats ;
675
677
int num_et_stats ;
676
678
/* Lock for updating the hwstats */
@@ -1550,25 +1552,37 @@ static int keystone_get_sset_count(struct net_device *ndev, int stringset)
1550
1552
}
1551
1553
}
1552
1554
1555
+ static void gbe_reset_mod_stats (struct gbe_priv * gbe_dev , int stats_mod )
1556
+ {
1557
+ void __iomem * base = gbe_dev -> hw_stats_regs [stats_mod ];
1558
+ u32 __iomem * p_stats_entry ;
1559
+ int i ;
1560
+
1561
+ for (i = 0 ; i < gbe_dev -> num_et_stats ; i ++ ) {
1562
+ if (gbe_dev -> et_stats [i ].type == stats_mod ) {
1563
+ p_stats_entry = base + gbe_dev -> et_stats [i ].offset ;
1564
+ gbe_dev -> hw_stats [i ] = 0 ;
1565
+ gbe_dev -> hw_stats_prev [i ] = readl (p_stats_entry );
1566
+ }
1567
+ }
1568
+ }
1569
+
1553
1570
static inline void gbe_update_hw_stats_entry (struct gbe_priv * gbe_dev ,
1554
1571
int et_stats_entry )
1555
1572
{
1556
1573
void __iomem * base = NULL ;
1557
- u32 __iomem * p ;
1558
- u32 tmp = 0 ;
1574
+ u32 __iomem * p_stats_entry ;
1575
+ u32 curr , delta ;
1559
1576
1560
1577
/* The hw_stats_regs pointers are already
1561
1578
* properly set to point to the right base:
1562
1579
*/
1563
1580
base = gbe_dev -> hw_stats_regs [gbe_dev -> et_stats [et_stats_entry ].type ];
1564
- p = base + gbe_dev -> et_stats [et_stats_entry ].offset ;
1565
- tmp = readl (p );
1566
- gbe_dev -> hw_stats [et_stats_entry ] += tmp ;
1567
-
1568
- /* write-to-decrement:
1569
- * new register value = old register value - write value
1570
- */
1571
- writel (tmp , p );
1581
+ p_stats_entry = base + gbe_dev -> et_stats [et_stats_entry ].offset ;
1582
+ curr = readl (p_stats_entry );
1583
+ delta = curr - gbe_dev -> hw_stats_prev [et_stats_entry ];
1584
+ gbe_dev -> hw_stats_prev [et_stats_entry ] = curr ;
1585
+ gbe_dev -> hw_stats [et_stats_entry ] += delta ;
1572
1586
}
1573
1587
1574
1588
static void gbe_update_stats (struct gbe_priv * gbe_dev , uint64_t * data )
@@ -1607,6 +1621,12 @@ static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev,
1607
1621
writel (val , GBE_REG_ADDR (gbe_dev , switch_regs , stat_port_en ));
1608
1622
}
1609
1623
1624
+ static void gbe_reset_mod_stats_ver14 (struct gbe_priv * gbe_dev , int stats_mod )
1625
+ {
1626
+ gbe_stats_mod_visible_ver14 (gbe_dev , stats_mod );
1627
+ gbe_reset_mod_stats (gbe_dev , stats_mod );
1628
+ }
1629
+
1610
1630
static void gbe_update_stats_ver14 (struct gbe_priv * gbe_dev , uint64_t * data )
1611
1631
{
1612
1632
u32 half_num_et_stats = (gbe_dev -> num_et_stats / 2 );
@@ -2560,6 +2580,7 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
2560
2580
}
2561
2581
gbe_dev -> xgbe_serdes_regs = regs ;
2562
2582
2583
+ gbe_dev -> num_stats_mods = gbe_dev -> max_num_ports ;
2563
2584
gbe_dev -> et_stats = xgbe10_et_stats ;
2564
2585
gbe_dev -> num_et_stats = ARRAY_SIZE (xgbe10_et_stats );
2565
2586
@@ -2571,6 +2592,16 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
2571
2592
return - ENOMEM ;
2572
2593
}
2573
2594
2595
+ gbe_dev -> hw_stats_prev =
2596
+ devm_kzalloc (gbe_dev -> dev ,
2597
+ gbe_dev -> num_et_stats * sizeof (u32 ),
2598
+ GFP_KERNEL );
2599
+ if (!gbe_dev -> hw_stats_prev ) {
2600
+ dev_err (gbe_dev -> dev ,
2601
+ "hw_stats_prev memory allocation failed\n" );
2602
+ return - ENOMEM ;
2603
+ }
2604
+
2574
2605
gbe_dev -> ss_version = XGBE_SS_VERSION_10 ;
2575
2606
gbe_dev -> sgmii_port_regs = gbe_dev -> ss_regs +
2576
2607
XGBE10_SGMII_MODULE_OFFSET ;
@@ -2668,6 +2699,7 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
2668
2699
}
2669
2700
gbe_dev -> switch_regs = regs ;
2670
2701
2702
+ gbe_dev -> num_stats_mods = gbe_dev -> max_num_slaves ;
2671
2703
gbe_dev -> et_stats = gbe13_et_stats ;
2672
2704
gbe_dev -> num_et_stats = ARRAY_SIZE (gbe13_et_stats );
2673
2705
@@ -2679,6 +2711,16 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
2679
2711
return - ENOMEM ;
2680
2712
}
2681
2713
2714
+ gbe_dev -> hw_stats_prev =
2715
+ devm_kzalloc (gbe_dev -> dev ,
2716
+ gbe_dev -> num_et_stats * sizeof (u32 ),
2717
+ GFP_KERNEL );
2718
+ if (!gbe_dev -> hw_stats_prev ) {
2719
+ dev_err (gbe_dev -> dev ,
2720
+ "hw_stats_prev memory allocation failed\n" );
2721
+ return - ENOMEM ;
2722
+ }
2723
+
2682
2724
gbe_dev -> sgmii_port_regs = gbe_dev -> ss_regs + GBE13_SGMII_MODULE_OFFSET ;
2683
2725
gbe_dev -> host_port_regs = gbe_dev -> switch_regs + GBE13_HOST_PORT_OFFSET ;
2684
2726
@@ -2722,6 +2764,7 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
2722
2764
void __iomem * regs ;
2723
2765
int i , ret ;
2724
2766
2767
+ gbe_dev -> num_stats_mods = gbe_dev -> max_num_ports ;
2725
2768
gbe_dev -> et_stats = gbenu_et_stats ;
2726
2769
2727
2770
if (IS_SS_ID_NU (gbe_dev ))
@@ -2739,6 +2782,16 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
2739
2782
return - ENOMEM ;
2740
2783
}
2741
2784
2785
+ gbe_dev -> hw_stats_prev =
2786
+ devm_kzalloc (gbe_dev -> dev ,
2787
+ gbe_dev -> num_et_stats * sizeof (u32 ),
2788
+ GFP_KERNEL );
2789
+ if (!gbe_dev -> hw_stats_prev ) {
2790
+ dev_err (gbe_dev -> dev ,
2791
+ "hw_stats_prev memory allocation failed\n" );
2792
+ return - ENOMEM ;
2793
+ }
2794
+
2742
2795
ret = of_address_to_resource (node , GBENU_SM_REG_INDEX , & res );
2743
2796
if (ret ) {
2744
2797
dev_err (gbe_dev -> dev ,
@@ -2797,7 +2850,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2797
2850
struct cpsw_ale_params ale_params ;
2798
2851
struct gbe_priv * gbe_dev ;
2799
2852
u32 slave_num ;
2800
- int ret = 0 ;
2853
+ int i , ret = 0 ;
2801
2854
2802
2855
if (!node ) {
2803
2856
dev_err (dev , "device tree info unavailable\n" );
@@ -2945,6 +2998,15 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2945
2998
/* initialize host port */
2946
2999
gbe_init_host_port (gbe_dev );
2947
3000
3001
+ spin_lock_bh (& gbe_dev -> hw_stats_lock );
3002
+ for (i = 0 ; i < gbe_dev -> num_stats_mods ; i ++ ) {
3003
+ if (gbe_dev -> ss_version == GBE_SS_VERSION_14 )
3004
+ gbe_reset_mod_stats_ver14 (gbe_dev , i );
3005
+ else
3006
+ gbe_reset_mod_stats (gbe_dev , i );
3007
+ }
3008
+ spin_unlock_bh (& gbe_dev -> hw_stats_lock );
3009
+
2948
3010
init_timer (& gbe_dev -> timer );
2949
3011
gbe_dev -> timer .data = (unsigned long )gbe_dev ;
2950
3012
gbe_dev -> timer .function = netcp_ethss_timer ;
@@ -2956,6 +3018,8 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2956
3018
quit :
2957
3019
if (gbe_dev -> hw_stats )
2958
3020
devm_kfree (dev , gbe_dev -> hw_stats );
3021
+ if (gbe_dev -> hw_stats_prev )
3022
+ devm_kfree (dev , gbe_dev -> hw_stats_prev );
2959
3023
cpsw_ale_destroy (gbe_dev -> ale );
2960
3024
if (gbe_dev -> ss_regs )
2961
3025
devm_iounmap (dev , gbe_dev -> ss_regs );
0 commit comments