112c2d0a5SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0+
212c2d0a5SHoratiu Vultur 
312c2d0a5SHoratiu Vultur #include <linux/netdevice.h>
412c2d0a5SHoratiu Vultur 
512c2d0a5SHoratiu Vultur #include "lan966x_main.h"
612c2d0a5SHoratiu Vultur 
712c2d0a5SHoratiu Vultur /* Number of traffic classes */
812c2d0a5SHoratiu Vultur #define LAN966X_NUM_TC			8
912c2d0a5SHoratiu Vultur #define LAN966X_STATS_CHECK_DELAY	(2 * HZ)
1012c2d0a5SHoratiu Vultur 
1112c2d0a5SHoratiu Vultur static const struct lan966x_stat_layout lan966x_stats_layout[] = {
1212c2d0a5SHoratiu Vultur 	{ .name = "rx_octets", .offset = 0x00, },
1312c2d0a5SHoratiu Vultur 	{ .name = "rx_unicast", .offset = 0x01, },
1412c2d0a5SHoratiu Vultur 	{ .name = "rx_multicast", .offset = 0x02 },
1512c2d0a5SHoratiu Vultur 	{ .name = "rx_broadcast", .offset = 0x03 },
1612c2d0a5SHoratiu Vultur 	{ .name = "rx_short", .offset = 0x04 },
1712c2d0a5SHoratiu Vultur 	{ .name = "rx_frag", .offset = 0x05 },
1812c2d0a5SHoratiu Vultur 	{ .name = "rx_jabber", .offset = 0x06 },
1912c2d0a5SHoratiu Vultur 	{ .name = "rx_crc", .offset = 0x07 },
2012c2d0a5SHoratiu Vultur 	{ .name = "rx_symbol_err", .offset = 0x08 },
2112c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_64", .offset = 0x09 },
2212c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_65_127", .offset = 0x0a},
2312c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_128_255", .offset = 0x0b},
2412c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_256_511", .offset = 0x0c },
2512c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_512_1023", .offset = 0x0d },
2612c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_1024_1526", .offset = 0x0e },
2712c2d0a5SHoratiu Vultur 	{ .name = "rx_sz_jumbo", .offset = 0x0f },
2812c2d0a5SHoratiu Vultur 	{ .name = "rx_pause", .offset = 0x10 },
2912c2d0a5SHoratiu Vultur 	{ .name = "rx_control", .offset = 0x11 },
3012c2d0a5SHoratiu Vultur 	{ .name = "rx_long", .offset = 0x12 },
3112c2d0a5SHoratiu Vultur 	{ .name = "rx_cat_drop", .offset = 0x13 },
3212c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_0", .offset = 0x14 },
3312c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_1", .offset = 0x15 },
3412c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_2", .offset = 0x16 },
3512c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_3", .offset = 0x17 },
3612c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_4", .offset = 0x18 },
3712c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_5", .offset = 0x19 },
3812c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_6", .offset = 0x1a },
3912c2d0a5SHoratiu Vultur 	{ .name = "rx_red_prio_7", .offset = 0x1b },
4012c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_0", .offset = 0x1c },
4112c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_1", .offset = 0x1d },
4212c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_2", .offset = 0x1e },
4312c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_3", .offset = 0x1f },
4412c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_4", .offset = 0x20 },
4512c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_5", .offset = 0x21 },
4612c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_6", .offset = 0x22 },
4712c2d0a5SHoratiu Vultur 	{ .name = "rx_yellow_prio_7", .offset = 0x23 },
4812c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_0", .offset = 0x24 },
4912c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_1", .offset = 0x25 },
5012c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_2", .offset = 0x26 },
5112c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_3", .offset = 0x27 },
5212c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_4", .offset = 0x28 },
5312c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_5", .offset = 0x29 },
5412c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_6", .offset = 0x2a },
5512c2d0a5SHoratiu Vultur 	{ .name = "rx_green_prio_7", .offset = 0x2b },
5612c2d0a5SHoratiu Vultur 	{ .name = "rx_assembly_err", .offset = 0x2c },
5712c2d0a5SHoratiu Vultur 	{ .name = "rx_smd_err", .offset = 0x2d },
5812c2d0a5SHoratiu Vultur 	{ .name = "rx_assembly_ok", .offset = 0x2e },
5912c2d0a5SHoratiu Vultur 	{ .name = "rx_merge_frag", .offset = 0x2f },
6012c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_octets", .offset = 0x30, },
6112c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_unicast", .offset = 0x31, },
6212c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_multicast", .offset = 0x32 },
6312c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_broadcast", .offset = 0x33 },
6412c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_short", .offset = 0x34 },
6512c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_frag", .offset = 0x35 },
6612c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_jabber", .offset = 0x36 },
6712c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_crc", .offset = 0x37 },
6812c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_symbol_err", .offset = 0x38 },
6912c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_64", .offset = 0x39 },
7012c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_65_127", .offset = 0x3a },
7112c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_128_255", .offset = 0x3b },
7212c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_256_511", .offset = 0x3c },
7312c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_512_1023", .offset = 0x3d },
7412c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },
7512c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_sz_jumbo", .offset = 0x3f },
7612c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_pause", .offset = 0x40 },
7712c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_control", .offset = 0x41 },
7812c2d0a5SHoratiu Vultur 	{ .name = "rx_pmac_long", .offset = 0x42 },
7912c2d0a5SHoratiu Vultur 
8012c2d0a5SHoratiu Vultur 	{ .name = "tx_octets", .offset = 0x80, },
8112c2d0a5SHoratiu Vultur 	{ .name = "tx_unicast", .offset = 0x81, },
8212c2d0a5SHoratiu Vultur 	{ .name = "tx_multicast", .offset = 0x82 },
8312c2d0a5SHoratiu Vultur 	{ .name = "tx_broadcast", .offset = 0x83 },
8412c2d0a5SHoratiu Vultur 	{ .name = "tx_col", .offset = 0x84 },
8512c2d0a5SHoratiu Vultur 	{ .name = "tx_drop", .offset = 0x85 },
8612c2d0a5SHoratiu Vultur 	{ .name = "tx_pause", .offset = 0x86 },
8712c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_64", .offset = 0x87 },
8812c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_65_127", .offset = 0x88 },
8912c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_128_255", .offset = 0x89 },
9012c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_256_511", .offset = 0x8a },
9112c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_512_1023", .offset = 0x8b },
9212c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_1024_1526", .offset = 0x8c },
9312c2d0a5SHoratiu Vultur 	{ .name = "tx_sz_jumbo", .offset = 0x8d },
9412c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_0", .offset = 0x8e },
9512c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_1", .offset = 0x8f },
9612c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_2", .offset = 0x90 },
9712c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_3", .offset = 0x91 },
9812c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_4", .offset = 0x92 },
9912c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_5", .offset = 0x93 },
10012c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_6", .offset = 0x94 },
10112c2d0a5SHoratiu Vultur 	{ .name = "tx_yellow_prio_7", .offset = 0x95 },
10212c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_0", .offset = 0x96 },
10312c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_1", .offset = 0x97 },
10412c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_2", .offset = 0x98 },
10512c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_3", .offset = 0x99 },
10612c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_4", .offset = 0x9a },
10712c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_5", .offset = 0x9b },
10812c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_6", .offset = 0x9c },
10912c2d0a5SHoratiu Vultur 	{ .name = "tx_green_prio_7", .offset = 0x9d },
11012c2d0a5SHoratiu Vultur 	{ .name = "tx_aged", .offset = 0x9e },
11112c2d0a5SHoratiu Vultur 	{ .name = "tx_llct", .offset = 0x9f },
11212c2d0a5SHoratiu Vultur 	{ .name = "tx_ct", .offset = 0xa0 },
11312c2d0a5SHoratiu Vultur 	{ .name = "tx_mm_hold", .offset = 0xa1 },
11412c2d0a5SHoratiu Vultur 	{ .name = "tx_merge_frag", .offset = 0xa2 },
11512c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_octets", .offset = 0xa3, },
11612c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_unicast", .offset = 0xa4, },
11712c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_multicast", .offset = 0xa5 },
11812c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_broadcast", .offset = 0xa6 },
11912c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_pause", .offset = 0xa7 },
12012c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_64", .offset = 0xa8 },
12112c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_65_127", .offset = 0xa9 },
12212c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_128_255", .offset = 0xaa },
12312c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_256_511", .offset = 0xab },
12412c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_512_1023", .offset = 0xac },
12512c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_1024_1526", .offset = 0xad },
12612c2d0a5SHoratiu Vultur 	{ .name = "tx_pmac_sz_jumbo", .offset = 0xae },
12712c2d0a5SHoratiu Vultur 
12812c2d0a5SHoratiu Vultur 	{ .name = "dr_local", .offset = 0x100 },
12912c2d0a5SHoratiu Vultur 	{ .name = "dr_tail", .offset = 0x101 },
13012c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_0", .offset = 0x102 },
13112c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_1", .offset = 0x103 },
13212c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_2", .offset = 0x104 },
13312c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_3", .offset = 0x105 },
13412c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_4", .offset = 0x106 },
13512c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_5", .offset = 0x107 },
13612c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_6", .offset = 0x108 },
13712c2d0a5SHoratiu Vultur 	{ .name = "dr_yellow_prio_7", .offset = 0x109 },
13812c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_0", .offset = 0x10a },
13912c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_1", .offset = 0x10b },
14012c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_2", .offset = 0x10c },
14112c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_3", .offset = 0x10d },
14212c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_4", .offset = 0x10e },
14312c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_5", .offset = 0x10f },
14412c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_6", .offset = 0x110 },
14512c2d0a5SHoratiu Vultur 	{ .name = "dr_green_prio_7", .offset = 0x111 },
14612c2d0a5SHoratiu Vultur };
14712c2d0a5SHoratiu Vultur 
14812c2d0a5SHoratiu Vultur /* The following numbers are indexes into lan966x_stats_layout[] */
14912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_OCT		  0
15012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_UC			  1
15112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_MC			  2
15212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_BC			  3
15312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SHORT		  4
15412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_FRAG		  5
15512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_JABBER		  6
15612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_CRC		  7
15712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SYMBOL_ERR		  8
15812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_64		  9
15912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_65_127		 10
16012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_128_255		 11
16112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_256_511		 12
16212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_512_1023	 13
16312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_1024_1526	 14
16412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SZ_JUMBO		 15
16512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PAUSE		 16
16612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_CONTROL		 17
16712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_LONG		 18
16812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_CAT_DROP		 19
16912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_0		 20
17012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_1		 21
17112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_2		 22
17212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_3		 23
17312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_4		 24
17412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_5		 25
17512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_6		 26
17612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_RED_PRIO_7		 27
17712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_0	 28
17812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_1	 29
17912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_2	 30
18012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_3	 31
18112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_4	 32
18212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_5	 33
18312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_6	 34
18412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_YELLOW_PRIO_7	 35
18512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_0	 36
18612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_1	 37
18712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_2	 38
18812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_3	 39
18912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_4	 40
19012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_5	 41
19112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_6	 42
19212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_GREEN_PRIO_7	 43
19312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_ASSEMBLY_ERR	 44
19412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_SMD_ERR		 45
19512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_ASSEMBLY_OK	 46
19612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_MERGE_FRAG		 47
19712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_OCT		 48
19812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_UC		 49
19912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_MC		 50
20012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_BC		 51
20112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SHORT		 52
20212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_FRAG		 53
20312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_JABBER	 54
20412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_CRC		 55
20512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SYMBOL_ERR	 56
20612c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_64		 57
20712c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_65_127	 58
20812c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_128_255	 59
20912c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_256_511	 60
21012c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_512_1023	 61
21112c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_1024_1526	 62
21212c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_SZ_JUMBO	 63
21312c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_PAUSE		 64
21412c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_CONTROL	 65
21512c2d0a5SHoratiu Vultur #define SYS_COUNT_RX_PMAC_LONG		 66
21612c2d0a5SHoratiu Vultur 
21712c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_OCT		 67
21812c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_UC			 68
21912c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_MC			 69
22012c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_BC			 70
22112c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_COL		 71
22212c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_DROP		 72
22312c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PAUSE		 73
22412c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_64		 74
22512c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_65_127		 75
22612c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_128_255		 76
22712c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_256_511		 77
22812c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_512_1023	 78
22912c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_1024_1526	 79
23012c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_SZ_JUMBO		 80
23112c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_0	 81
23212c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_1	 82
23312c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_2	 83
23412c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_3	 84
23512c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_4	 85
23612c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_5	 86
23712c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_6	 87
23812c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_YELLOW_PRIO_7	 88
23912c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_0	 89
24012c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_1	 90
24112c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_2	 91
24212c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_3	 92
24312c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_4	 93
24412c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_5	 94
24512c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_6	 95
24612c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_GREEN_PRIO_7	 96
24712c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_AGED		 97
24812c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_LLCT		 98
24912c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_CT			 99
25012c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_MM_HOLD		100
25112c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_MERGE_FRAG		101
25212c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_OCT		102
25312c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_UC		103
25412c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_MC		104
25512c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_BC		105
25612c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_PAUSE		106
25712c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_64		107
25812c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_65_127	108
25912c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_128_255	109
26012c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_256_511	110
26112c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_512_1023	111
26212c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_1024_1526	112
26312c2d0a5SHoratiu Vultur #define SYS_COUNT_TX_PMAC_SZ_JUMBO	113
26412c2d0a5SHoratiu Vultur 
26512c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_LOCAL		114
26612c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_TAIL		115
26712c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_0	116
26812c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_1	117
26912c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_2	118
27012c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_3	119
27112c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_4	120
27212c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_5	121
27312c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_6	122
27412c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_YELLOW_PRIO_7	123
27512c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_0	124
27612c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_1	125
27712c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_2	126
27812c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_3	127
27912c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_4	128
28012c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_5	129
28112c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_6	130
28212c2d0a5SHoratiu Vultur #define SYS_COUNT_DR_GREEN_PRIO_7	131
28312c2d0a5SHoratiu Vultur 
28412c2d0a5SHoratiu Vultur /* Add a possibly wrapping 32 bit value to a 64 bit counter */
lan966x_add_cnt(u64 * cnt,u32 val)28512c2d0a5SHoratiu Vultur static void lan966x_add_cnt(u64 *cnt, u32 val)
28612c2d0a5SHoratiu Vultur {
28712c2d0a5SHoratiu Vultur 	if (val < (*cnt & U32_MAX))
28812c2d0a5SHoratiu Vultur 		*cnt += (u64)1 << 32; /* value has wrapped */
28912c2d0a5SHoratiu Vultur 
29012c2d0a5SHoratiu Vultur 	*cnt = (*cnt & ~(u64)U32_MAX) + val;
29112c2d0a5SHoratiu Vultur }
29212c2d0a5SHoratiu Vultur 
lan966x_stats_update(struct lan966x * lan966x)29312c2d0a5SHoratiu Vultur static void lan966x_stats_update(struct lan966x *lan966x)
29412c2d0a5SHoratiu Vultur {
29512c2d0a5SHoratiu Vultur 	int i, j;
29612c2d0a5SHoratiu Vultur 
29712c2d0a5SHoratiu Vultur 	mutex_lock(&lan966x->stats_lock);
29812c2d0a5SHoratiu Vultur 
29912c2d0a5SHoratiu Vultur 	for (i = 0; i < lan966x->num_phys_ports; i++) {
30012c2d0a5SHoratiu Vultur 		uint idx = i * lan966x->num_stats;
30112c2d0a5SHoratiu Vultur 
30212c2d0a5SHoratiu Vultur 		lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),
30312c2d0a5SHoratiu Vultur 		       lan966x, SYS_STAT_CFG);
30412c2d0a5SHoratiu Vultur 
30512c2d0a5SHoratiu Vultur 		for (j = 0; j < lan966x->num_stats; j++) {
30612c2d0a5SHoratiu Vultur 			u32 offset = lan966x->stats_layout[j].offset;
30712c2d0a5SHoratiu Vultur 
30812c2d0a5SHoratiu Vultur 			lan966x_add_cnt(&lan966x->stats[idx++],
30912c2d0a5SHoratiu Vultur 					lan_rd(lan966x, SYS_CNT(offset)));
31012c2d0a5SHoratiu Vultur 		}
31112c2d0a5SHoratiu Vultur 	}
31212c2d0a5SHoratiu Vultur 
31312c2d0a5SHoratiu Vultur 	mutex_unlock(&lan966x->stats_lock);
31412c2d0a5SHoratiu Vultur }
31512c2d0a5SHoratiu Vultur 
lan966x_get_sset_count(struct net_device * dev,int sset)31612c2d0a5SHoratiu Vultur static int lan966x_get_sset_count(struct net_device *dev, int sset)
31712c2d0a5SHoratiu Vultur {
31812c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
31912c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
32012c2d0a5SHoratiu Vultur 
32112c2d0a5SHoratiu Vultur 	if (sset != ETH_SS_STATS)
32212c2d0a5SHoratiu Vultur 		return -EOPNOTSUPP;
32312c2d0a5SHoratiu Vultur 
32412c2d0a5SHoratiu Vultur 	return lan966x->num_stats;
32512c2d0a5SHoratiu Vultur }
32612c2d0a5SHoratiu Vultur 
lan966x_get_strings(struct net_device * netdev,u32 sset,u8 * data)32712c2d0a5SHoratiu Vultur static void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)
32812c2d0a5SHoratiu Vultur {
32912c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(netdev);
33012c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
33112c2d0a5SHoratiu Vultur 	int i;
33212c2d0a5SHoratiu Vultur 
33312c2d0a5SHoratiu Vultur 	if (sset != ETH_SS_STATS)
33412c2d0a5SHoratiu Vultur 		return;
33512c2d0a5SHoratiu Vultur 
33612c2d0a5SHoratiu Vultur 	for (i = 0; i < lan966x->num_stats; i++)
33712c2d0a5SHoratiu Vultur 		memcpy(data + i * ETH_GSTRING_LEN,
33812c2d0a5SHoratiu Vultur 		       lan966x->stats_layout[i].name, ETH_GSTRING_LEN);
33912c2d0a5SHoratiu Vultur }
34012c2d0a5SHoratiu Vultur 
lan966x_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * data)34112c2d0a5SHoratiu Vultur static void lan966x_get_ethtool_stats(struct net_device *dev,
34212c2d0a5SHoratiu Vultur 				      struct ethtool_stats *stats, u64 *data)
34312c2d0a5SHoratiu Vultur {
34412c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
34512c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
34612c2d0a5SHoratiu Vultur 	int i;
34712c2d0a5SHoratiu Vultur 
34812c2d0a5SHoratiu Vultur 	/* check and update now */
34912c2d0a5SHoratiu Vultur 	lan966x_stats_update(lan966x);
35012c2d0a5SHoratiu Vultur 
35112c2d0a5SHoratiu Vultur 	/* Copy all counters */
35212c2d0a5SHoratiu Vultur 	for (i = 0; i < lan966x->num_stats; i++)
35312c2d0a5SHoratiu Vultur 		*data++ = lan966x->stats[port->chip_port *
35412c2d0a5SHoratiu Vultur 					 lan966x->num_stats + i];
35512c2d0a5SHoratiu Vultur }
35612c2d0a5SHoratiu Vultur 
lan966x_get_eth_mac_stats(struct net_device * dev,struct ethtool_eth_mac_stats * mac_stats)35712c2d0a5SHoratiu Vultur static void lan966x_get_eth_mac_stats(struct net_device *dev,
35812c2d0a5SHoratiu Vultur 				      struct ethtool_eth_mac_stats *mac_stats)
35912c2d0a5SHoratiu Vultur {
36012c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
36112c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
36212c2d0a5SHoratiu Vultur 	u32 idx;
36312c2d0a5SHoratiu Vultur 
36412c2d0a5SHoratiu Vultur 	lan966x_stats_update(lan966x);
36512c2d0a5SHoratiu Vultur 
36612c2d0a5SHoratiu Vultur 	idx = port->chip_port * lan966x->num_stats;
36712c2d0a5SHoratiu Vultur 
36812c2d0a5SHoratiu Vultur 	mutex_lock(&lan966x->stats_lock);
36912c2d0a5SHoratiu Vultur 
37012c2d0a5SHoratiu Vultur 	mac_stats->FramesTransmittedOK =
37112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_UC] +
37212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_MC] +
37312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_BC] +
37412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +
37512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +
37612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
37712c2d0a5SHoratiu Vultur 	mac_stats->SingleCollisionFrames =
37812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_COL];
37912c2d0a5SHoratiu Vultur 	mac_stats->MultipleCollisionFrames = 0;
38012c2d0a5SHoratiu Vultur 	mac_stats->FramesReceivedOK =
38112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_UC] +
38212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_MC] +
38312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_BC];
38412c2d0a5SHoratiu Vultur 	mac_stats->FrameCheckSequenceErrors =
38512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
38612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_CRC];
38712c2d0a5SHoratiu Vultur 	mac_stats->AlignmentErrors = 0;
38812c2d0a5SHoratiu Vultur 	mac_stats->OctetsTransmittedOK =
38912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_OCT] +
39012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
39112c2d0a5SHoratiu Vultur 	mac_stats->FramesWithDeferredXmissions =
39212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];
39312c2d0a5SHoratiu Vultur 	mac_stats->LateCollisions = 0;
39412c2d0a5SHoratiu Vultur 	mac_stats->FramesAbortedDueToXSColls = 0;
39512c2d0a5SHoratiu Vultur 	mac_stats->FramesLostDueToIntMACXmitError = 0;
39612c2d0a5SHoratiu Vultur 	mac_stats->CarrierSenseErrors = 0;
39712c2d0a5SHoratiu Vultur 	mac_stats->OctetsReceivedOK =
39812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_OCT];
39912c2d0a5SHoratiu Vultur 	mac_stats->FramesLostDueToIntMACRcvError = 0;
40012c2d0a5SHoratiu Vultur 	mac_stats->MulticastFramesXmittedOK =
40112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_MC] +
40212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];
40312c2d0a5SHoratiu Vultur 	mac_stats->BroadcastFramesXmittedOK =
40412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_BC] +
40512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
40612c2d0a5SHoratiu Vultur 	mac_stats->FramesWithExcessiveDeferral = 0;
40712c2d0a5SHoratiu Vultur 	mac_stats->MulticastFramesReceivedOK =
40812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_MC];
40912c2d0a5SHoratiu Vultur 	mac_stats->BroadcastFramesReceivedOK =
41012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_BC];
41112c2d0a5SHoratiu Vultur 	mac_stats->InRangeLengthErrors =
41212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
41312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
41412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
41512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
41612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
41712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];
41812c2d0a5SHoratiu Vultur 	mac_stats->OutOfRangeLengthField =
41912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
42012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
42112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
42212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
42312c2d0a5SHoratiu Vultur 	mac_stats->FrameTooLongErrors =
42412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
42512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
42612c2d0a5SHoratiu Vultur 
42712c2d0a5SHoratiu Vultur 	mutex_unlock(&lan966x->stats_lock);
42812c2d0a5SHoratiu Vultur }
42912c2d0a5SHoratiu Vultur 
43012c2d0a5SHoratiu Vultur static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
43112c2d0a5SHoratiu Vultur 	{    0,    64 },
43212c2d0a5SHoratiu Vultur 	{   65,   127 },
43312c2d0a5SHoratiu Vultur 	{  128,   255 },
43412c2d0a5SHoratiu Vultur 	{  256,   511 },
43512c2d0a5SHoratiu Vultur 	{  512,  1023 },
43612c2d0a5SHoratiu Vultur 	{ 1024,  1518 },
43712c2d0a5SHoratiu Vultur 	{ 1519, 10239 },
43812c2d0a5SHoratiu Vultur 	{}
43912c2d0a5SHoratiu Vultur };
44012c2d0a5SHoratiu Vultur 
lan966x_get_eth_rmon_stats(struct net_device * dev,struct ethtool_rmon_stats * rmon_stats,const struct ethtool_rmon_hist_range ** ranges)44112c2d0a5SHoratiu Vultur static void lan966x_get_eth_rmon_stats(struct net_device *dev,
44212c2d0a5SHoratiu Vultur 				       struct ethtool_rmon_stats *rmon_stats,
44312c2d0a5SHoratiu Vultur 				       const struct ethtool_rmon_hist_range **ranges)
44412c2d0a5SHoratiu Vultur {
44512c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
44612c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
44712c2d0a5SHoratiu Vultur 	u32 idx;
44812c2d0a5SHoratiu Vultur 
44912c2d0a5SHoratiu Vultur 	lan966x_stats_update(lan966x);
45012c2d0a5SHoratiu Vultur 
45112c2d0a5SHoratiu Vultur 	idx = port->chip_port * lan966x->num_stats;
45212c2d0a5SHoratiu Vultur 
45312c2d0a5SHoratiu Vultur 	mutex_lock(&lan966x->stats_lock);
45412c2d0a5SHoratiu Vultur 
45512c2d0a5SHoratiu Vultur 	rmon_stats->undersize_pkts =
45612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
45712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];
45812c2d0a5SHoratiu Vultur 	rmon_stats->oversize_pkts =
45912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
46012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
46112c2d0a5SHoratiu Vultur 	rmon_stats->fragments =
46212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
46312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];
46412c2d0a5SHoratiu Vultur 	rmon_stats->jabbers =
46512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
46612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];
46712c2d0a5SHoratiu Vultur 	rmon_stats->hist[0] =
46812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
46912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];
47012c2d0a5SHoratiu Vultur 	rmon_stats->hist[1] =
47112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
47212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];
47312c2d0a5SHoratiu Vultur 	rmon_stats->hist[2] =
47412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
47512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];
47612c2d0a5SHoratiu Vultur 	rmon_stats->hist[3] =
47712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
47812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];
47912c2d0a5SHoratiu Vultur 	rmon_stats->hist[4] =
48012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
48112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];
48212c2d0a5SHoratiu Vultur 	rmon_stats->hist[5] =
48312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
48412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
48512c2d0a5SHoratiu Vultur 	rmon_stats->hist[6] =
48612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
48712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
48812c2d0a5SHoratiu Vultur 
48912c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[0] =
49012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
49112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];
49212c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[1] =
49312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
49412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];
49512c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[2] =
49612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
49712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];
49812c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[3] =
49912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
50012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];
50112c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[4] =
50212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
50312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];
50412c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[5] =
50512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
50612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
50712c2d0a5SHoratiu Vultur 	rmon_stats->hist_tx[6] =
50812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
50912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
51012c2d0a5SHoratiu Vultur 
51112c2d0a5SHoratiu Vultur 	mutex_unlock(&lan966x->stats_lock);
51212c2d0a5SHoratiu Vultur 
51312c2d0a5SHoratiu Vultur 	*ranges = lan966x_rmon_ranges;
51412c2d0a5SHoratiu Vultur }
51512c2d0a5SHoratiu Vultur 
lan966x_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)51612c2d0a5SHoratiu Vultur static int lan966x_get_link_ksettings(struct net_device *ndev,
51712c2d0a5SHoratiu Vultur 				      struct ethtool_link_ksettings *cmd)
51812c2d0a5SHoratiu Vultur {
51912c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(ndev);
52012c2d0a5SHoratiu Vultur 
52112c2d0a5SHoratiu Vultur 	return phylink_ethtool_ksettings_get(port->phylink, cmd);
52212c2d0a5SHoratiu Vultur }
52312c2d0a5SHoratiu Vultur 
lan966x_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)52412c2d0a5SHoratiu Vultur static int lan966x_set_link_ksettings(struct net_device *ndev,
52512c2d0a5SHoratiu Vultur 				      const struct ethtool_link_ksettings *cmd)
52612c2d0a5SHoratiu Vultur {
52712c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(ndev);
52812c2d0a5SHoratiu Vultur 
52912c2d0a5SHoratiu Vultur 	return phylink_ethtool_ksettings_set(port->phylink, cmd);
53012c2d0a5SHoratiu Vultur }
53112c2d0a5SHoratiu Vultur 
lan966x_get_pauseparam(struct net_device * dev,struct ethtool_pauseparam * pause)53212c2d0a5SHoratiu Vultur static void lan966x_get_pauseparam(struct net_device *dev,
53312c2d0a5SHoratiu Vultur 				   struct ethtool_pauseparam *pause)
53412c2d0a5SHoratiu Vultur {
53512c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
53612c2d0a5SHoratiu Vultur 
53712c2d0a5SHoratiu Vultur 	phylink_ethtool_get_pauseparam(port->phylink, pause);
53812c2d0a5SHoratiu Vultur }
53912c2d0a5SHoratiu Vultur 
lan966x_set_pauseparam(struct net_device * dev,struct ethtool_pauseparam * pause)54012c2d0a5SHoratiu Vultur static int lan966x_set_pauseparam(struct net_device *dev,
54112c2d0a5SHoratiu Vultur 				  struct ethtool_pauseparam *pause)
54212c2d0a5SHoratiu Vultur {
54312c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
54412c2d0a5SHoratiu Vultur 
54512c2d0a5SHoratiu Vultur 	return phylink_ethtool_set_pauseparam(port->phylink, pause);
54612c2d0a5SHoratiu Vultur }
54712c2d0a5SHoratiu Vultur 
lan966x_get_ts_info(struct net_device * dev,struct ethtool_ts_info * info)548966f2e1aSHoratiu Vultur static int lan966x_get_ts_info(struct net_device *dev,
549966f2e1aSHoratiu Vultur 			       struct ethtool_ts_info *info)
550966f2e1aSHoratiu Vultur {
551966f2e1aSHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
552966f2e1aSHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
553966f2e1aSHoratiu Vultur 	struct lan966x_phc *phc;
554966f2e1aSHoratiu Vultur 
555966f2e1aSHoratiu Vultur 	if (!lan966x->ptp)
556966f2e1aSHoratiu Vultur 		return ethtool_op_get_ts_info(dev, info);
557966f2e1aSHoratiu Vultur 
558966f2e1aSHoratiu Vultur 	phc = &lan966x->phc[LAN966X_PHC_PORT];
559966f2e1aSHoratiu Vultur 
560966f2e1aSHoratiu Vultur 	info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
561966f2e1aSHoratiu Vultur 	if (info->phc_index == -1) {
562966f2e1aSHoratiu Vultur 		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
563966f2e1aSHoratiu Vultur 					 SOF_TIMESTAMPING_RX_SOFTWARE |
564966f2e1aSHoratiu Vultur 					 SOF_TIMESTAMPING_SOFTWARE;
565966f2e1aSHoratiu Vultur 		return 0;
566966f2e1aSHoratiu Vultur 	}
567966f2e1aSHoratiu Vultur 	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
568966f2e1aSHoratiu Vultur 				 SOF_TIMESTAMPING_RX_SOFTWARE |
569966f2e1aSHoratiu Vultur 				 SOF_TIMESTAMPING_SOFTWARE |
570966f2e1aSHoratiu Vultur 				 SOF_TIMESTAMPING_TX_HARDWARE |
571966f2e1aSHoratiu Vultur 				 SOF_TIMESTAMPING_RX_HARDWARE |
572966f2e1aSHoratiu Vultur 				 SOF_TIMESTAMPING_RAW_HARDWARE;
573966f2e1aSHoratiu Vultur 	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
574966f2e1aSHoratiu Vultur 			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
575966f2e1aSHoratiu Vultur 	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
576966f2e1aSHoratiu Vultur 			   BIT(HWTSTAMP_FILTER_ALL);
577966f2e1aSHoratiu Vultur 
578966f2e1aSHoratiu Vultur 	return 0;
579966f2e1aSHoratiu Vultur }
580966f2e1aSHoratiu Vultur 
58112c2d0a5SHoratiu Vultur const struct ethtool_ops lan966x_ethtool_ops = {
58212c2d0a5SHoratiu Vultur 	.get_link_ksettings     = lan966x_get_link_ksettings,
58312c2d0a5SHoratiu Vultur 	.set_link_ksettings     = lan966x_set_link_ksettings,
58412c2d0a5SHoratiu Vultur 	.get_pauseparam		= lan966x_get_pauseparam,
58512c2d0a5SHoratiu Vultur 	.set_pauseparam		= lan966x_set_pauseparam,
58612c2d0a5SHoratiu Vultur 	.get_sset_count		= lan966x_get_sset_count,
58712c2d0a5SHoratiu Vultur 	.get_strings		= lan966x_get_strings,
58812c2d0a5SHoratiu Vultur 	.get_ethtool_stats	= lan966x_get_ethtool_stats,
58912c2d0a5SHoratiu Vultur 	.get_eth_mac_stats      = lan966x_get_eth_mac_stats,
59012c2d0a5SHoratiu Vultur 	.get_rmon_stats		= lan966x_get_eth_rmon_stats,
59112c2d0a5SHoratiu Vultur 	.get_link		= ethtool_op_get_link,
592966f2e1aSHoratiu Vultur 	.get_ts_info		= lan966x_get_ts_info,
59312c2d0a5SHoratiu Vultur };
59412c2d0a5SHoratiu Vultur 
lan966x_check_stats_work(struct work_struct * work)59512c2d0a5SHoratiu Vultur static void lan966x_check_stats_work(struct work_struct *work)
59612c2d0a5SHoratiu Vultur {
59712c2d0a5SHoratiu Vultur 	struct delayed_work *del_work = to_delayed_work(work);
59812c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = container_of(del_work, struct lan966x,
59912c2d0a5SHoratiu Vultur 					       stats_work);
60012c2d0a5SHoratiu Vultur 
60112c2d0a5SHoratiu Vultur 	lan966x_stats_update(lan966x);
60212c2d0a5SHoratiu Vultur 
60312c2d0a5SHoratiu Vultur 	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
60412c2d0a5SHoratiu Vultur 			   LAN966X_STATS_CHECK_DELAY);
60512c2d0a5SHoratiu Vultur }
60612c2d0a5SHoratiu Vultur 
lan966x_stats_get(struct net_device * dev,struct rtnl_link_stats64 * stats)60712c2d0a5SHoratiu Vultur void lan966x_stats_get(struct net_device *dev,
60812c2d0a5SHoratiu Vultur 		       struct rtnl_link_stats64 *stats)
60912c2d0a5SHoratiu Vultur {
61012c2d0a5SHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
61112c2d0a5SHoratiu Vultur 	struct lan966x *lan966x = port->lan966x;
61212c2d0a5SHoratiu Vultur 	u32 idx;
61312c2d0a5SHoratiu Vultur 	int i;
61412c2d0a5SHoratiu Vultur 
61512c2d0a5SHoratiu Vultur 	idx = port->chip_port * lan966x->num_stats;
61612c2d0a5SHoratiu Vultur 
61712c2d0a5SHoratiu Vultur 	mutex_lock(&lan966x->stats_lock);
61812c2d0a5SHoratiu Vultur 
61912c2d0a5SHoratiu Vultur 	stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
62012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];
62112c2d0a5SHoratiu Vultur 
62212c2d0a5SHoratiu Vultur 	stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
62312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
62412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
62512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
62612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
62712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
62812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
62912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
63012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
63112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
63212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
63312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +
63412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
63512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
63612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
63712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
63812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +
63912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +
64012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +
64112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +
64212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +
64312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +
64412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];
64512c2d0a5SHoratiu Vultur 
64612c2d0a5SHoratiu Vultur 	stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +
64712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];
64812c2d0a5SHoratiu Vultur 
64912c2d0a5SHoratiu Vultur 	stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
65012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
65112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
65212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_CRC] +
65312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
65412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG];
65512c2d0a5SHoratiu Vultur 
65612c2d0a5SHoratiu Vultur 	stats->rx_dropped = dev->stats.rx_dropped +
65712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
65812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
659f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
660f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
661f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
662f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
663f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
664f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
665f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
666f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
667f8c1c66bSHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
66812c2d0a5SHoratiu Vultur 
66912c2d0a5SHoratiu Vultur 	for (i = 0; i < LAN966X_NUM_TC; i++) {
67012c2d0a5SHoratiu Vultur 		stats->rx_dropped +=
67112c2d0a5SHoratiu Vultur 			(lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +
67212c2d0a5SHoratiu Vultur 			 lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);
67312c2d0a5SHoratiu Vultur 	}
67412c2d0a5SHoratiu Vultur 
67512c2d0a5SHoratiu Vultur 	/* Get Tx stats */
67612c2d0a5SHoratiu Vultur 	stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +
67712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
67812c2d0a5SHoratiu Vultur 
67912c2d0a5SHoratiu Vultur 	stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
68012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
68112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
68212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
68312c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
68412c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
68512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +
68612c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +
68712c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +
68812c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +
68912c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +
69012c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +
69112c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +
69212c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];
69312c2d0a5SHoratiu Vultur 
69412c2d0a5SHoratiu Vultur 	stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +
69512c2d0a5SHoratiu Vultur 		lan966x->stats[idx + SYS_COUNT_TX_AGED];
69612c2d0a5SHoratiu Vultur 
69712c2d0a5SHoratiu Vultur 	stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];
69812c2d0a5SHoratiu Vultur 
69912c2d0a5SHoratiu Vultur 	mutex_unlock(&lan966x->stats_lock);
70012c2d0a5SHoratiu Vultur }
70112c2d0a5SHoratiu Vultur 
lan966x_stats_init(struct lan966x * lan966x)70212c2d0a5SHoratiu Vultur int lan966x_stats_init(struct lan966x *lan966x)
70312c2d0a5SHoratiu Vultur {
70412c2d0a5SHoratiu Vultur 	char queue_name[32];
70512c2d0a5SHoratiu Vultur 
70612c2d0a5SHoratiu Vultur 	lan966x->stats_layout = lan966x_stats_layout;
70712c2d0a5SHoratiu Vultur 	lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);
70812c2d0a5SHoratiu Vultur 	lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *
70912c2d0a5SHoratiu Vultur 				      lan966x->num_stats,
71012c2d0a5SHoratiu Vultur 				      sizeof(u64), GFP_KERNEL);
71112c2d0a5SHoratiu Vultur 	if (!lan966x->stats)
71212c2d0a5SHoratiu Vultur 		return -ENOMEM;
71312c2d0a5SHoratiu Vultur 
71412c2d0a5SHoratiu Vultur 	/* Init stats worker */
71512c2d0a5SHoratiu Vultur 	mutex_init(&lan966x->stats_lock);
71612c2d0a5SHoratiu Vultur 	snprintf(queue_name, sizeof(queue_name), "%s-stats",
71712c2d0a5SHoratiu Vultur 		 dev_name(lan966x->dev));
71812c2d0a5SHoratiu Vultur 	lan966x->stats_queue = create_singlethread_workqueue(queue_name);
719*ba86af37SShang XiaoJing 	if (!lan966x->stats_queue)
720*ba86af37SShang XiaoJing 		return -ENOMEM;
721*ba86af37SShang XiaoJing 
72212c2d0a5SHoratiu Vultur 	INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
72312c2d0a5SHoratiu Vultur 	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
72412c2d0a5SHoratiu Vultur 			   LAN966X_STATS_CHECK_DELAY);
72512c2d0a5SHoratiu Vultur 
72612c2d0a5SHoratiu Vultur 	return 0;
72712c2d0a5SHoratiu Vultur }
728