summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti/icssg/icssg_prueth.c
diff options
context:
space:
mode:
authorMD Danish Anwar <danishanwar@ti.com>2023-08-01 14:44:25 +0530
committerDavid S. Miller <davem@davemloft.net>2023-08-02 10:38:11 +0100
commitc1e10d5dc7a1be8d4eba8560540e20bd03c2be01 (patch)
tree9d5ee5132610c50b60c7e0c66d77a9a83e82d503 /drivers/net/ethernet/ti/icssg/icssg_prueth.c
parent128d5874c0822105ae9556d5435fb8562aff2e3b (diff)
downloadlwn-c1e10d5dc7a1be8d4eba8560540e20bd03c2be01.tar.gz
lwn-c1e10d5dc7a1be8d4eba8560540e20bd03c2be01.zip
net: ti: icssg-prueth: Add ICSSG Stats
Add icssg_stats.c to help dump, icssg related driver statistics. ICSSG has hardware registers for providing statistics like total rx bytes, total tx bytes, etc. These registers are of 32 bits and hence in case of 1G link, they overflows in around 32 seconds. The behaviour of these registers is such that they don't roll back to 0 after overflow but rather stay at UINT_MAX. These registers support a feature where the value written to them is subtracted from the register. This feature can be utilized to fix the overflowing of stats. This solution uses a Workqueues based solution where a function gets called before the registers overflow (every 25 seconds in 1G link, 25000 seconds in 100M link), this function saves the register values in local variables and writes the last read value to the register. So any update during the read will be taken care of. Signed-off-by: MD Danish Anwar <danishanwar@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/icssg/icssg_prueth.c')
-rw-r--r--drivers/net/ethernet/ti/icssg/icssg_prueth.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 1869e38f898f..d0bb4db11b30 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -8,6 +8,7 @@
#include <linux/bitops.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dma/ti-cppi5.h>
#include <linux/etherdevice.h>
@@ -1090,6 +1091,8 @@ static int emac_ndo_open(struct net_device *ndev)
prueth->emacs_initialized++;
+ queue_work(system_long_wq, &emac->stats_work.work);
+
return 0;
reset_tx_chan:
@@ -1164,6 +1167,9 @@ static int emac_ndo_stop(struct net_device *ndev)
cancel_work_sync(&emac->rx_mode_work);
+ /* Destroying the queued work in ndo_stop() */
+ cancel_delayed_work_sync(&emac->stats_work);
+
/* stop PRUs */
prueth_emac_stop(emac);
@@ -1313,6 +1319,8 @@ static int prueth_netdev_init(struct prueth *prueth,
}
INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work);
+ INIT_DELAYED_WORK(&emac->stats_work, emac_stats_work_handler);
+
ret = pruss_request_mem_region(prueth->pruss,
port == PRUETH_PORT_MII0 ?
PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,