162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/netdevice.h>
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include "lan966x_main.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/* Number of traffic classes */
862306a36Sopenharmony_ci#define LAN966X_NUM_TC			8
962306a36Sopenharmony_ci#define LAN966X_STATS_CHECK_DELAY	(2 * HZ)
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistatic const struct lan966x_stat_layout lan966x_stats_layout[] = {
1262306a36Sopenharmony_ci	{ .name = "rx_octets", .offset = 0x00, },
1362306a36Sopenharmony_ci	{ .name = "rx_unicast", .offset = 0x01, },
1462306a36Sopenharmony_ci	{ .name = "rx_multicast", .offset = 0x02 },
1562306a36Sopenharmony_ci	{ .name = "rx_broadcast", .offset = 0x03 },
1662306a36Sopenharmony_ci	{ .name = "rx_short", .offset = 0x04 },
1762306a36Sopenharmony_ci	{ .name = "rx_frag", .offset = 0x05 },
1862306a36Sopenharmony_ci	{ .name = "rx_jabber", .offset = 0x06 },
1962306a36Sopenharmony_ci	{ .name = "rx_crc", .offset = 0x07 },
2062306a36Sopenharmony_ci	{ .name = "rx_symbol_err", .offset = 0x08 },
2162306a36Sopenharmony_ci	{ .name = "rx_sz_64", .offset = 0x09 },
2262306a36Sopenharmony_ci	{ .name = "rx_sz_65_127", .offset = 0x0a},
2362306a36Sopenharmony_ci	{ .name = "rx_sz_128_255", .offset = 0x0b},
2462306a36Sopenharmony_ci	{ .name = "rx_sz_256_511", .offset = 0x0c },
2562306a36Sopenharmony_ci	{ .name = "rx_sz_512_1023", .offset = 0x0d },
2662306a36Sopenharmony_ci	{ .name = "rx_sz_1024_1526", .offset = 0x0e },
2762306a36Sopenharmony_ci	{ .name = "rx_sz_jumbo", .offset = 0x0f },
2862306a36Sopenharmony_ci	{ .name = "rx_pause", .offset = 0x10 },
2962306a36Sopenharmony_ci	{ .name = "rx_control", .offset = 0x11 },
3062306a36Sopenharmony_ci	{ .name = "rx_long", .offset = 0x12 },
3162306a36Sopenharmony_ci	{ .name = "rx_cat_drop", .offset = 0x13 },
3262306a36Sopenharmony_ci	{ .name = "rx_red_prio_0", .offset = 0x14 },
3362306a36Sopenharmony_ci	{ .name = "rx_red_prio_1", .offset = 0x15 },
3462306a36Sopenharmony_ci	{ .name = "rx_red_prio_2", .offset = 0x16 },
3562306a36Sopenharmony_ci	{ .name = "rx_red_prio_3", .offset = 0x17 },
3662306a36Sopenharmony_ci	{ .name = "rx_red_prio_4", .offset = 0x18 },
3762306a36Sopenharmony_ci	{ .name = "rx_red_prio_5", .offset = 0x19 },
3862306a36Sopenharmony_ci	{ .name = "rx_red_prio_6", .offset = 0x1a },
3962306a36Sopenharmony_ci	{ .name = "rx_red_prio_7", .offset = 0x1b },
4062306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_0", .offset = 0x1c },
4162306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_1", .offset = 0x1d },
4262306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_2", .offset = 0x1e },
4362306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_3", .offset = 0x1f },
4462306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_4", .offset = 0x20 },
4562306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_5", .offset = 0x21 },
4662306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_6", .offset = 0x22 },
4762306a36Sopenharmony_ci	{ .name = "rx_yellow_prio_7", .offset = 0x23 },
4862306a36Sopenharmony_ci	{ .name = "rx_green_prio_0", .offset = 0x24 },
4962306a36Sopenharmony_ci	{ .name = "rx_green_prio_1", .offset = 0x25 },
5062306a36Sopenharmony_ci	{ .name = "rx_green_prio_2", .offset = 0x26 },
5162306a36Sopenharmony_ci	{ .name = "rx_green_prio_3", .offset = 0x27 },
5262306a36Sopenharmony_ci	{ .name = "rx_green_prio_4", .offset = 0x28 },
5362306a36Sopenharmony_ci	{ .name = "rx_green_prio_5", .offset = 0x29 },
5462306a36Sopenharmony_ci	{ .name = "rx_green_prio_6", .offset = 0x2a },
5562306a36Sopenharmony_ci	{ .name = "rx_green_prio_7", .offset = 0x2b },
5662306a36Sopenharmony_ci	{ .name = "rx_assembly_err", .offset = 0x2c },
5762306a36Sopenharmony_ci	{ .name = "rx_smd_err", .offset = 0x2d },
5862306a36Sopenharmony_ci	{ .name = "rx_assembly_ok", .offset = 0x2e },
5962306a36Sopenharmony_ci	{ .name = "rx_merge_frag", .offset = 0x2f },
6062306a36Sopenharmony_ci	{ .name = "rx_pmac_octets", .offset = 0x30, },
6162306a36Sopenharmony_ci	{ .name = "rx_pmac_unicast", .offset = 0x31, },
6262306a36Sopenharmony_ci	{ .name = "rx_pmac_multicast", .offset = 0x32 },
6362306a36Sopenharmony_ci	{ .name = "rx_pmac_broadcast", .offset = 0x33 },
6462306a36Sopenharmony_ci	{ .name = "rx_pmac_short", .offset = 0x34 },
6562306a36Sopenharmony_ci	{ .name = "rx_pmac_frag", .offset = 0x35 },
6662306a36Sopenharmony_ci	{ .name = "rx_pmac_jabber", .offset = 0x36 },
6762306a36Sopenharmony_ci	{ .name = "rx_pmac_crc", .offset = 0x37 },
6862306a36Sopenharmony_ci	{ .name = "rx_pmac_symbol_err", .offset = 0x38 },
6962306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_64", .offset = 0x39 },
7062306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_65_127", .offset = 0x3a },
7162306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_128_255", .offset = 0x3b },
7262306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_256_511", .offset = 0x3c },
7362306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_512_1023", .offset = 0x3d },
7462306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },
7562306a36Sopenharmony_ci	{ .name = "rx_pmac_sz_jumbo", .offset = 0x3f },
7662306a36Sopenharmony_ci	{ .name = "rx_pmac_pause", .offset = 0x40 },
7762306a36Sopenharmony_ci	{ .name = "rx_pmac_control", .offset = 0x41 },
7862306a36Sopenharmony_ci	{ .name = "rx_pmac_long", .offset = 0x42 },
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	{ .name = "tx_octets", .offset = 0x80, },
8162306a36Sopenharmony_ci	{ .name = "tx_unicast", .offset = 0x81, },
8262306a36Sopenharmony_ci	{ .name = "tx_multicast", .offset = 0x82 },
8362306a36Sopenharmony_ci	{ .name = "tx_broadcast", .offset = 0x83 },
8462306a36Sopenharmony_ci	{ .name = "tx_col", .offset = 0x84 },
8562306a36Sopenharmony_ci	{ .name = "tx_drop", .offset = 0x85 },
8662306a36Sopenharmony_ci	{ .name = "tx_pause", .offset = 0x86 },
8762306a36Sopenharmony_ci	{ .name = "tx_sz_64", .offset = 0x87 },
8862306a36Sopenharmony_ci	{ .name = "tx_sz_65_127", .offset = 0x88 },
8962306a36Sopenharmony_ci	{ .name = "tx_sz_128_255", .offset = 0x89 },
9062306a36Sopenharmony_ci	{ .name = "tx_sz_256_511", .offset = 0x8a },
9162306a36Sopenharmony_ci	{ .name = "tx_sz_512_1023", .offset = 0x8b },
9262306a36Sopenharmony_ci	{ .name = "tx_sz_1024_1526", .offset = 0x8c },
9362306a36Sopenharmony_ci	{ .name = "tx_sz_jumbo", .offset = 0x8d },
9462306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_0", .offset = 0x8e },
9562306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_1", .offset = 0x8f },
9662306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_2", .offset = 0x90 },
9762306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_3", .offset = 0x91 },
9862306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_4", .offset = 0x92 },
9962306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_5", .offset = 0x93 },
10062306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_6", .offset = 0x94 },
10162306a36Sopenharmony_ci	{ .name = "tx_yellow_prio_7", .offset = 0x95 },
10262306a36Sopenharmony_ci	{ .name = "tx_green_prio_0", .offset = 0x96 },
10362306a36Sopenharmony_ci	{ .name = "tx_green_prio_1", .offset = 0x97 },
10462306a36Sopenharmony_ci	{ .name = "tx_green_prio_2", .offset = 0x98 },
10562306a36Sopenharmony_ci	{ .name = "tx_green_prio_3", .offset = 0x99 },
10662306a36Sopenharmony_ci	{ .name = "tx_green_prio_4", .offset = 0x9a },
10762306a36Sopenharmony_ci	{ .name = "tx_green_prio_5", .offset = 0x9b },
10862306a36Sopenharmony_ci	{ .name = "tx_green_prio_6", .offset = 0x9c },
10962306a36Sopenharmony_ci	{ .name = "tx_green_prio_7", .offset = 0x9d },
11062306a36Sopenharmony_ci	{ .name = "tx_aged", .offset = 0x9e },
11162306a36Sopenharmony_ci	{ .name = "tx_llct", .offset = 0x9f },
11262306a36Sopenharmony_ci	{ .name = "tx_ct", .offset = 0xa0 },
11362306a36Sopenharmony_ci	{ .name = "tx_mm_hold", .offset = 0xa1 },
11462306a36Sopenharmony_ci	{ .name = "tx_merge_frag", .offset = 0xa2 },
11562306a36Sopenharmony_ci	{ .name = "tx_pmac_octets", .offset = 0xa3, },
11662306a36Sopenharmony_ci	{ .name = "tx_pmac_unicast", .offset = 0xa4, },
11762306a36Sopenharmony_ci	{ .name = "tx_pmac_multicast", .offset = 0xa5 },
11862306a36Sopenharmony_ci	{ .name = "tx_pmac_broadcast", .offset = 0xa6 },
11962306a36Sopenharmony_ci	{ .name = "tx_pmac_pause", .offset = 0xa7 },
12062306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_64", .offset = 0xa8 },
12162306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_65_127", .offset = 0xa9 },
12262306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_128_255", .offset = 0xaa },
12362306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_256_511", .offset = 0xab },
12462306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_512_1023", .offset = 0xac },
12562306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_1024_1526", .offset = 0xad },
12662306a36Sopenharmony_ci	{ .name = "tx_pmac_sz_jumbo", .offset = 0xae },
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	{ .name = "dr_local", .offset = 0x100 },
12962306a36Sopenharmony_ci	{ .name = "dr_tail", .offset = 0x101 },
13062306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_0", .offset = 0x102 },
13162306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_1", .offset = 0x103 },
13262306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_2", .offset = 0x104 },
13362306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_3", .offset = 0x105 },
13462306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_4", .offset = 0x106 },
13562306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_5", .offset = 0x107 },
13662306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_6", .offset = 0x108 },
13762306a36Sopenharmony_ci	{ .name = "dr_yellow_prio_7", .offset = 0x109 },
13862306a36Sopenharmony_ci	{ .name = "dr_green_prio_0", .offset = 0x10a },
13962306a36Sopenharmony_ci	{ .name = "dr_green_prio_1", .offset = 0x10b },
14062306a36Sopenharmony_ci	{ .name = "dr_green_prio_2", .offset = 0x10c },
14162306a36Sopenharmony_ci	{ .name = "dr_green_prio_3", .offset = 0x10d },
14262306a36Sopenharmony_ci	{ .name = "dr_green_prio_4", .offset = 0x10e },
14362306a36Sopenharmony_ci	{ .name = "dr_green_prio_5", .offset = 0x10f },
14462306a36Sopenharmony_ci	{ .name = "dr_green_prio_6", .offset = 0x110 },
14562306a36Sopenharmony_ci	{ .name = "dr_green_prio_7", .offset = 0x111 },
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* The following numbers are indexes into lan966x_stats_layout[] */
14962306a36Sopenharmony_ci#define SYS_COUNT_RX_OCT		  0
15062306a36Sopenharmony_ci#define SYS_COUNT_RX_UC			  1
15162306a36Sopenharmony_ci#define SYS_COUNT_RX_MC			  2
15262306a36Sopenharmony_ci#define SYS_COUNT_RX_BC			  3
15362306a36Sopenharmony_ci#define SYS_COUNT_RX_SHORT		  4
15462306a36Sopenharmony_ci#define SYS_COUNT_RX_FRAG		  5
15562306a36Sopenharmony_ci#define SYS_COUNT_RX_JABBER		  6
15662306a36Sopenharmony_ci#define SYS_COUNT_RX_CRC		  7
15762306a36Sopenharmony_ci#define SYS_COUNT_RX_SYMBOL_ERR		  8
15862306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_64		  9
15962306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_65_127		 10
16062306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_128_255		 11
16162306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_256_511		 12
16262306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_512_1023	 13
16362306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_1024_1526	 14
16462306a36Sopenharmony_ci#define SYS_COUNT_RX_SZ_JUMBO		 15
16562306a36Sopenharmony_ci#define SYS_COUNT_RX_PAUSE		 16
16662306a36Sopenharmony_ci#define SYS_COUNT_RX_CONTROL		 17
16762306a36Sopenharmony_ci#define SYS_COUNT_RX_LONG		 18
16862306a36Sopenharmony_ci#define SYS_COUNT_RX_CAT_DROP		 19
16962306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_0		 20
17062306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_1		 21
17162306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_2		 22
17262306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_3		 23
17362306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_4		 24
17462306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_5		 25
17562306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_6		 26
17662306a36Sopenharmony_ci#define SYS_COUNT_RX_RED_PRIO_7		 27
17762306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_0	 28
17862306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_1	 29
17962306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_2	 30
18062306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_3	 31
18162306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_4	 32
18262306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_5	 33
18362306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_6	 34
18462306a36Sopenharmony_ci#define SYS_COUNT_RX_YELLOW_PRIO_7	 35
18562306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_0	 36
18662306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_1	 37
18762306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_2	 38
18862306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_3	 39
18962306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_4	 40
19062306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_5	 41
19162306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_6	 42
19262306a36Sopenharmony_ci#define SYS_COUNT_RX_GREEN_PRIO_7	 43
19362306a36Sopenharmony_ci#define SYS_COUNT_RX_ASSEMBLY_ERR	 44
19462306a36Sopenharmony_ci#define SYS_COUNT_RX_SMD_ERR		 45
19562306a36Sopenharmony_ci#define SYS_COUNT_RX_ASSEMBLY_OK	 46
19662306a36Sopenharmony_ci#define SYS_COUNT_RX_MERGE_FRAG		 47
19762306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_OCT		 48
19862306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_UC		 49
19962306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_MC		 50
20062306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_BC		 51
20162306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SHORT		 52
20262306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_FRAG		 53
20362306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_JABBER	 54
20462306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_CRC		 55
20562306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SYMBOL_ERR	 56
20662306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_64		 57
20762306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_65_127	 58
20862306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_128_255	 59
20962306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_256_511	 60
21062306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_512_1023	 61
21162306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_1024_1526	 62
21262306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_SZ_JUMBO	 63
21362306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_PAUSE		 64
21462306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_CONTROL	 65
21562306a36Sopenharmony_ci#define SYS_COUNT_RX_PMAC_LONG		 66
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci#define SYS_COUNT_TX_OCT		 67
21862306a36Sopenharmony_ci#define SYS_COUNT_TX_UC			 68
21962306a36Sopenharmony_ci#define SYS_COUNT_TX_MC			 69
22062306a36Sopenharmony_ci#define SYS_COUNT_TX_BC			 70
22162306a36Sopenharmony_ci#define SYS_COUNT_TX_COL		 71
22262306a36Sopenharmony_ci#define SYS_COUNT_TX_DROP		 72
22362306a36Sopenharmony_ci#define SYS_COUNT_TX_PAUSE		 73
22462306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_64		 74
22562306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_65_127		 75
22662306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_128_255		 76
22762306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_256_511		 77
22862306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_512_1023	 78
22962306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_1024_1526	 79
23062306a36Sopenharmony_ci#define SYS_COUNT_TX_SZ_JUMBO		 80
23162306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_0	 81
23262306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_1	 82
23362306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_2	 83
23462306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_3	 84
23562306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_4	 85
23662306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_5	 86
23762306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_6	 87
23862306a36Sopenharmony_ci#define SYS_COUNT_TX_YELLOW_PRIO_7	 88
23962306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_0	 89
24062306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_1	 90
24162306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_2	 91
24262306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_3	 92
24362306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_4	 93
24462306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_5	 94
24562306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_6	 95
24662306a36Sopenharmony_ci#define SYS_COUNT_TX_GREEN_PRIO_7	 96
24762306a36Sopenharmony_ci#define SYS_COUNT_TX_AGED		 97
24862306a36Sopenharmony_ci#define SYS_COUNT_TX_LLCT		 98
24962306a36Sopenharmony_ci#define SYS_COUNT_TX_CT			 99
25062306a36Sopenharmony_ci#define SYS_COUNT_TX_MM_HOLD		100
25162306a36Sopenharmony_ci#define SYS_COUNT_TX_MERGE_FRAG		101
25262306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_OCT		102
25362306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_UC		103
25462306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_MC		104
25562306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_BC		105
25662306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_PAUSE		106
25762306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_64		107
25862306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_65_127	108
25962306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_128_255	109
26062306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_256_511	110
26162306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_512_1023	111
26262306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_1024_1526	112
26362306a36Sopenharmony_ci#define SYS_COUNT_TX_PMAC_SZ_JUMBO	113
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci#define SYS_COUNT_DR_LOCAL		114
26662306a36Sopenharmony_ci#define SYS_COUNT_DR_TAIL		115
26762306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_0	116
26862306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_1	117
26962306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_2	118
27062306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_3	119
27162306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_4	120
27262306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_5	121
27362306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_6	122
27462306a36Sopenharmony_ci#define SYS_COUNT_DR_YELLOW_PRIO_7	123
27562306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_0	124
27662306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_1	125
27762306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_2	126
27862306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_3	127
27962306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_4	128
28062306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_5	129
28162306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_6	130
28262306a36Sopenharmony_ci#define SYS_COUNT_DR_GREEN_PRIO_7	131
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci/* Add a possibly wrapping 32 bit value to a 64 bit counter */
28562306a36Sopenharmony_cistatic void lan966x_add_cnt(u64 *cnt, u32 val)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	if (val < (*cnt & U32_MAX))
28862306a36Sopenharmony_ci		*cnt += (u64)1 << 32; /* value has wrapped */
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	*cnt = (*cnt & ~(u64)U32_MAX) + val;
29162306a36Sopenharmony_ci}
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_cistatic void lan966x_stats_update(struct lan966x *lan966x)
29462306a36Sopenharmony_ci{
29562306a36Sopenharmony_ci	int i, j;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	mutex_lock(&lan966x->stats_lock);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	for (i = 0; i < lan966x->num_phys_ports; i++) {
30062306a36Sopenharmony_ci		uint idx = i * lan966x->num_stats;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci		lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),
30362306a36Sopenharmony_ci		       lan966x, SYS_STAT_CFG);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci		for (j = 0; j < lan966x->num_stats; j++) {
30662306a36Sopenharmony_ci			u32 offset = lan966x->stats_layout[j].offset;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci			lan966x_add_cnt(&lan966x->stats[idx++],
30962306a36Sopenharmony_ci					lan_rd(lan966x, SYS_CNT(offset)));
31062306a36Sopenharmony_ci		}
31162306a36Sopenharmony_ci	}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	mutex_unlock(&lan966x->stats_lock);
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic int lan966x_get_sset_count(struct net_device *dev, int sset)
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
31962306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	if (sset != ETH_SS_STATS)
32262306a36Sopenharmony_ci		return -EOPNOTSUPP;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	return lan966x->num_stats;
32562306a36Sopenharmony_ci}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistatic void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(netdev);
33062306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
33162306a36Sopenharmony_ci	int i;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	if (sset != ETH_SS_STATS)
33462306a36Sopenharmony_ci		return;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	for (i = 0; i < lan966x->num_stats; i++)
33762306a36Sopenharmony_ci		memcpy(data + i * ETH_GSTRING_LEN,
33862306a36Sopenharmony_ci		       lan966x->stats_layout[i].name, ETH_GSTRING_LEN);
33962306a36Sopenharmony_ci}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic void lan966x_get_ethtool_stats(struct net_device *dev,
34262306a36Sopenharmony_ci				      struct ethtool_stats *stats, u64 *data)
34362306a36Sopenharmony_ci{
34462306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
34562306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
34662306a36Sopenharmony_ci	int i;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	/* check and update now */
34962306a36Sopenharmony_ci	lan966x_stats_update(lan966x);
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	/* Copy all counters */
35262306a36Sopenharmony_ci	for (i = 0; i < lan966x->num_stats; i++)
35362306a36Sopenharmony_ci		*data++ = lan966x->stats[port->chip_port *
35462306a36Sopenharmony_ci					 lan966x->num_stats + i];
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic void lan966x_get_eth_mac_stats(struct net_device *dev,
35862306a36Sopenharmony_ci				      struct ethtool_eth_mac_stats *mac_stats)
35962306a36Sopenharmony_ci{
36062306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
36162306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
36262306a36Sopenharmony_ci	u32 idx;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	lan966x_stats_update(lan966x);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	idx = port->chip_port * lan966x->num_stats;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	mutex_lock(&lan966x->stats_lock);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	mac_stats->FramesTransmittedOK =
37162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_UC] +
37262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_MC] +
37362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_BC] +
37462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +
37562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +
37662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
37762306a36Sopenharmony_ci	mac_stats->SingleCollisionFrames =
37862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_COL];
37962306a36Sopenharmony_ci	mac_stats->MultipleCollisionFrames = 0;
38062306a36Sopenharmony_ci	mac_stats->FramesReceivedOK =
38162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_UC] +
38262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_MC] +
38362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_BC];
38462306a36Sopenharmony_ci	mac_stats->FrameCheckSequenceErrors =
38562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
38662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_CRC];
38762306a36Sopenharmony_ci	mac_stats->AlignmentErrors = 0;
38862306a36Sopenharmony_ci	mac_stats->OctetsTransmittedOK =
38962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_OCT] +
39062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
39162306a36Sopenharmony_ci	mac_stats->FramesWithDeferredXmissions =
39262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];
39362306a36Sopenharmony_ci	mac_stats->LateCollisions = 0;
39462306a36Sopenharmony_ci	mac_stats->FramesAbortedDueToXSColls = 0;
39562306a36Sopenharmony_ci	mac_stats->FramesLostDueToIntMACXmitError = 0;
39662306a36Sopenharmony_ci	mac_stats->CarrierSenseErrors = 0;
39762306a36Sopenharmony_ci	mac_stats->OctetsReceivedOK =
39862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_OCT];
39962306a36Sopenharmony_ci	mac_stats->FramesLostDueToIntMACRcvError = 0;
40062306a36Sopenharmony_ci	mac_stats->MulticastFramesXmittedOK =
40162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_MC] +
40262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];
40362306a36Sopenharmony_ci	mac_stats->BroadcastFramesXmittedOK =
40462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_BC] +
40562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
40662306a36Sopenharmony_ci	mac_stats->FramesWithExcessiveDeferral = 0;
40762306a36Sopenharmony_ci	mac_stats->MulticastFramesReceivedOK =
40862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_MC];
40962306a36Sopenharmony_ci	mac_stats->BroadcastFramesReceivedOK =
41062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_BC];
41162306a36Sopenharmony_ci	mac_stats->InRangeLengthErrors =
41262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
41362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
41462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
41562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
41662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
41762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];
41862306a36Sopenharmony_ci	mac_stats->OutOfRangeLengthField =
41962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
42062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
42162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
42262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
42362306a36Sopenharmony_ci	mac_stats->FrameTooLongErrors =
42462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
42562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	mutex_unlock(&lan966x->stats_lock);
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
43162306a36Sopenharmony_ci	{    0,    64 },
43262306a36Sopenharmony_ci	{   65,   127 },
43362306a36Sopenharmony_ci	{  128,   255 },
43462306a36Sopenharmony_ci	{  256,   511 },
43562306a36Sopenharmony_ci	{  512,  1023 },
43662306a36Sopenharmony_ci	{ 1024,  1518 },
43762306a36Sopenharmony_ci	{ 1519, 10239 },
43862306a36Sopenharmony_ci	{}
43962306a36Sopenharmony_ci};
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_cistatic void lan966x_get_eth_rmon_stats(struct net_device *dev,
44262306a36Sopenharmony_ci				       struct ethtool_rmon_stats *rmon_stats,
44362306a36Sopenharmony_ci				       const struct ethtool_rmon_hist_range **ranges)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
44662306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
44762306a36Sopenharmony_ci	u32 idx;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	lan966x_stats_update(lan966x);
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	idx = port->chip_port * lan966x->num_stats;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	mutex_lock(&lan966x->stats_lock);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	rmon_stats->undersize_pkts =
45662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
45762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];
45862306a36Sopenharmony_ci	rmon_stats->oversize_pkts =
45962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
46062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
46162306a36Sopenharmony_ci	rmon_stats->fragments =
46262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
46362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];
46462306a36Sopenharmony_ci	rmon_stats->jabbers =
46562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
46662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];
46762306a36Sopenharmony_ci	rmon_stats->hist[0] =
46862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
46962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];
47062306a36Sopenharmony_ci	rmon_stats->hist[1] =
47162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
47262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];
47362306a36Sopenharmony_ci	rmon_stats->hist[2] =
47462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
47562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];
47662306a36Sopenharmony_ci	rmon_stats->hist[3] =
47762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
47862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];
47962306a36Sopenharmony_ci	rmon_stats->hist[4] =
48062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
48162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];
48262306a36Sopenharmony_ci	rmon_stats->hist[5] =
48362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
48462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
48562306a36Sopenharmony_ci	rmon_stats->hist[6] =
48662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
48762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	rmon_stats->hist_tx[0] =
49062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
49162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];
49262306a36Sopenharmony_ci	rmon_stats->hist_tx[1] =
49362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
49462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];
49562306a36Sopenharmony_ci	rmon_stats->hist_tx[2] =
49662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
49762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];
49862306a36Sopenharmony_ci	rmon_stats->hist_tx[3] =
49962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
50062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];
50162306a36Sopenharmony_ci	rmon_stats->hist_tx[4] =
50262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
50362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];
50462306a36Sopenharmony_ci	rmon_stats->hist_tx[5] =
50562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
50662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
50762306a36Sopenharmony_ci	rmon_stats->hist_tx[6] =
50862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
50962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	mutex_unlock(&lan966x->stats_lock);
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	*ranges = lan966x_rmon_ranges;
51462306a36Sopenharmony_ci}
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_cistatic int lan966x_get_link_ksettings(struct net_device *ndev,
51762306a36Sopenharmony_ci				      struct ethtool_link_ksettings *cmd)
51862306a36Sopenharmony_ci{
51962306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(ndev);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	return phylink_ethtool_ksettings_get(port->phylink, cmd);
52262306a36Sopenharmony_ci}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_cistatic int lan966x_set_link_ksettings(struct net_device *ndev,
52562306a36Sopenharmony_ci				      const struct ethtool_link_ksettings *cmd)
52662306a36Sopenharmony_ci{
52762306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(ndev);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	return phylink_ethtool_ksettings_set(port->phylink, cmd);
53062306a36Sopenharmony_ci}
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic void lan966x_get_pauseparam(struct net_device *dev,
53362306a36Sopenharmony_ci				   struct ethtool_pauseparam *pause)
53462306a36Sopenharmony_ci{
53562306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	phylink_ethtool_get_pauseparam(port->phylink, pause);
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic int lan966x_set_pauseparam(struct net_device *dev,
54162306a36Sopenharmony_ci				  struct ethtool_pauseparam *pause)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	return phylink_ethtool_set_pauseparam(port->phylink, pause);
54662306a36Sopenharmony_ci}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_cistatic int lan966x_get_ts_info(struct net_device *dev,
54962306a36Sopenharmony_ci			       struct ethtool_ts_info *info)
55062306a36Sopenharmony_ci{
55162306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
55262306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
55362306a36Sopenharmony_ci	struct lan966x_phc *phc;
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	if (!lan966x->ptp)
55662306a36Sopenharmony_ci		return ethtool_op_get_ts_info(dev, info);
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	phc = &lan966x->phc[LAN966X_PHC_PORT];
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
56162306a36Sopenharmony_ci	if (info->phc_index == -1) {
56262306a36Sopenharmony_ci		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
56362306a36Sopenharmony_ci					 SOF_TIMESTAMPING_RX_SOFTWARE |
56462306a36Sopenharmony_ci					 SOF_TIMESTAMPING_SOFTWARE;
56562306a36Sopenharmony_ci		return 0;
56662306a36Sopenharmony_ci	}
56762306a36Sopenharmony_ci	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
56862306a36Sopenharmony_ci				 SOF_TIMESTAMPING_RX_SOFTWARE |
56962306a36Sopenharmony_ci				 SOF_TIMESTAMPING_SOFTWARE |
57062306a36Sopenharmony_ci				 SOF_TIMESTAMPING_TX_HARDWARE |
57162306a36Sopenharmony_ci				 SOF_TIMESTAMPING_RX_HARDWARE |
57262306a36Sopenharmony_ci				 SOF_TIMESTAMPING_RAW_HARDWARE;
57362306a36Sopenharmony_ci	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
57462306a36Sopenharmony_ci			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
57562306a36Sopenharmony_ci	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
57662306a36Sopenharmony_ci			   BIT(HWTSTAMP_FILTER_ALL);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	return 0;
57962306a36Sopenharmony_ci}
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ciconst struct ethtool_ops lan966x_ethtool_ops = {
58262306a36Sopenharmony_ci	.get_link_ksettings     = lan966x_get_link_ksettings,
58362306a36Sopenharmony_ci	.set_link_ksettings     = lan966x_set_link_ksettings,
58462306a36Sopenharmony_ci	.get_pauseparam		= lan966x_get_pauseparam,
58562306a36Sopenharmony_ci	.set_pauseparam		= lan966x_set_pauseparam,
58662306a36Sopenharmony_ci	.get_sset_count		= lan966x_get_sset_count,
58762306a36Sopenharmony_ci	.get_strings		= lan966x_get_strings,
58862306a36Sopenharmony_ci	.get_ethtool_stats	= lan966x_get_ethtool_stats,
58962306a36Sopenharmony_ci	.get_eth_mac_stats      = lan966x_get_eth_mac_stats,
59062306a36Sopenharmony_ci	.get_rmon_stats		= lan966x_get_eth_rmon_stats,
59162306a36Sopenharmony_ci	.get_link		= ethtool_op_get_link,
59262306a36Sopenharmony_ci	.get_ts_info		= lan966x_get_ts_info,
59362306a36Sopenharmony_ci};
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistatic void lan966x_check_stats_work(struct work_struct *work)
59662306a36Sopenharmony_ci{
59762306a36Sopenharmony_ci	struct delayed_work *del_work = to_delayed_work(work);
59862306a36Sopenharmony_ci	struct lan966x *lan966x = container_of(del_work, struct lan966x,
59962306a36Sopenharmony_ci					       stats_work);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	lan966x_stats_update(lan966x);
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
60462306a36Sopenharmony_ci			   LAN966X_STATS_CHECK_DELAY);
60562306a36Sopenharmony_ci}
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_civoid lan966x_stats_get(struct net_device *dev,
60862306a36Sopenharmony_ci		       struct rtnl_link_stats64 *stats)
60962306a36Sopenharmony_ci{
61062306a36Sopenharmony_ci	struct lan966x_port *port = netdev_priv(dev);
61162306a36Sopenharmony_ci	struct lan966x *lan966x = port->lan966x;
61262306a36Sopenharmony_ci	u32 idx;
61362306a36Sopenharmony_ci	int i;
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	idx = port->chip_port * lan966x->num_stats;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	mutex_lock(&lan966x->stats_lock);
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
62062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
62362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
62462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
62562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
62662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
62762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
62862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
62962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
63062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
63162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
63262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
63362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +
63462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
63562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
63662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
63762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
63862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +
63962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +
64062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +
64162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +
64262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +
64362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +
64462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +
64762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
65062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
65162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
65262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
65362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
65462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG];
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	stats->rx_dropped = dev->stats.rx_dropped +
65762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
65862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
65962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
66062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
66162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
66262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
66362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
66462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
66562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
66662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
66762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	for (i = 0; i < LAN966X_NUM_TC; i++) {
67062306a36Sopenharmony_ci		stats->rx_dropped +=
67162306a36Sopenharmony_ci			(lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +
67262306a36Sopenharmony_ci			 lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);
67362306a36Sopenharmony_ci	}
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	/* Get Tx stats */
67662306a36Sopenharmony_ci	stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +
67762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
68062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
68162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
68262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
68362306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
68462306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
68562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +
68662306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +
68762306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +
68862306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +
68962306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +
69062306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +
69162306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +
69262306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +
69562306a36Sopenharmony_ci		lan966x->stats[idx + SYS_COUNT_TX_AGED];
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	mutex_unlock(&lan966x->stats_lock);
70062306a36Sopenharmony_ci}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ciint lan966x_stats_init(struct lan966x *lan966x)
70362306a36Sopenharmony_ci{
70462306a36Sopenharmony_ci	char queue_name[32];
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	lan966x->stats_layout = lan966x_stats_layout;
70762306a36Sopenharmony_ci	lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);
70862306a36Sopenharmony_ci	lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *
70962306a36Sopenharmony_ci				      lan966x->num_stats,
71062306a36Sopenharmony_ci				      sizeof(u64), GFP_KERNEL);
71162306a36Sopenharmony_ci	if (!lan966x->stats)
71262306a36Sopenharmony_ci		return -ENOMEM;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	/* Init stats worker */
71562306a36Sopenharmony_ci	mutex_init(&lan966x->stats_lock);
71662306a36Sopenharmony_ci	snprintf(queue_name, sizeof(queue_name), "%s-stats",
71762306a36Sopenharmony_ci		 dev_name(lan966x->dev));
71862306a36Sopenharmony_ci	lan966x->stats_queue = create_singlethread_workqueue(queue_name);
71962306a36Sopenharmony_ci	if (!lan966x->stats_queue)
72062306a36Sopenharmony_ci		return -ENOMEM;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
72362306a36Sopenharmony_ci	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
72462306a36Sopenharmony_ci			   LAN966X_STATS_CHECK_DELAY);
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	return 0;
72762306a36Sopenharmony_ci}
728