1 // SPDX-License-Identifier: GPL-2.0
2 /* Texas Instruments ICSSG Ethernet driver
4 * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
8 #include "icssg_prueth.h"
9 #include "icssg_stats.h"
10 #include <linux/regmap.h>
12 #define ICSSG_TX_PACKET_OFFSET 0xA0
13 #define ICSSG_TX_BYTE_OFFSET 0xEC
14 #define ICSSG_FW_STATS_BASE 0x0248
16 static u32 stats_base
[] = { 0x54c, /* Slice 0 stats start */
17 0xb18, /* Slice 1 stats start */
20 void emac_update_hardware_stats(struct prueth_emac
*emac
)
22 struct prueth
*prueth
= emac
->prueth
;
23 int slice
= prueth_emac_slice(emac
);
24 u32 base
= stats_base
[slice
];
29 for (i
= 0; i
< ARRAY_SIZE(icssg_all_miig_stats
); i
++) {
30 regmap_read(prueth
->miig_rt
,
31 base
+ icssg_all_miig_stats
[i
].offset
,
33 regmap_write(prueth
->miig_rt
,
34 base
+ icssg_all_miig_stats
[i
].offset
,
37 if (icssg_all_miig_stats
[i
].offset
== ICSSG_TX_PACKET_OFFSET
)
40 emac
->stats
[i
] += val
;
41 if (icssg_all_miig_stats
[i
].offset
== ICSSG_TX_BYTE_OFFSET
)
42 emac
->stats
[i
] -= tx_pkt_cnt
* 8;
45 if (prueth
->pa_stats
) {
46 for (i
= 0; i
< ARRAY_SIZE(icssg_all_pa_stats
); i
++) {
47 reg
= ICSSG_FW_STATS_BASE
+
48 icssg_all_pa_stats
[i
].offset
*
49 PRUETH_NUM_MACS
+ slice
* sizeof(u32
);
50 regmap_read(prueth
->pa_stats
, reg
, &val
);
51 emac
->pa_stats
[i
] += val
;
56 void icssg_stats_work_handler(struct work_struct
*work
)
58 struct prueth_emac
*emac
= container_of(work
, struct prueth_emac
,
60 emac_update_hardware_stats(emac
);
62 queue_delayed_work(system_long_wq
, &emac
->stats_work
,
63 msecs_to_jiffies((STATS_TIME_LIMIT_1G_MS
* 1000) / emac
->speed
));
65 EXPORT_SYMBOL_GPL(icssg_stats_work_handler
);
67 int emac_get_stat_by_name(struct prueth_emac
*emac
, char *stat_name
)
71 for (i
= 0; i
< ARRAY_SIZE(icssg_all_miig_stats
); i
++) {
72 if (!strcmp(icssg_all_miig_stats
[i
].name
, stat_name
))
73 return emac
->stats
[icssg_all_miig_stats
[i
].offset
/ sizeof(u32
)];
76 if (emac
->prueth
->pa_stats
) {
77 for (i
= 0; i
< ARRAY_SIZE(icssg_all_pa_stats
); i
++) {
78 if (!strcmp(icssg_all_pa_stats
[i
].name
, stat_name
))
79 return emac
->pa_stats
[icssg_all_pa_stats
[i
].offset
/ sizeof(u32
)];
83 netdev_err(emac
->ndev
, "Invalid stats %s\n", stat_name
);