brintos

brintos / linux-shallow public Read only

0
0
Text · 25.0 KiB · 2474dfd Raw
717 lines · c
1// SPDX-License-Identifier: GPL-2.0+2 3#include <linux/netdevice.h>4 5#include "lan966x_main.h"6 7/* Number of traffic classes */8#define LAN966X_NUM_TC			89#define LAN966X_STATS_CHECK_DELAY	(2 * HZ)10 11static const struct lan966x_stat_layout lan966x_stats_layout[] = {12	{ .name = "rx_octets", .offset = 0x00, },13	{ .name = "rx_unicast", .offset = 0x01, },14	{ .name = "rx_multicast", .offset = 0x02 },15	{ .name = "rx_broadcast", .offset = 0x03 },16	{ .name = "rx_short", .offset = 0x04 },17	{ .name = "rx_frag", .offset = 0x05 },18	{ .name = "rx_jabber", .offset = 0x06 },19	{ .name = "rx_crc", .offset = 0x07 },20	{ .name = "rx_symbol_err", .offset = 0x08 },21	{ .name = "rx_sz_64", .offset = 0x09 },22	{ .name = "rx_sz_65_127", .offset = 0x0a},23	{ .name = "rx_sz_128_255", .offset = 0x0b},24	{ .name = "rx_sz_256_511", .offset = 0x0c },25	{ .name = "rx_sz_512_1023", .offset = 0x0d },26	{ .name = "rx_sz_1024_1526", .offset = 0x0e },27	{ .name = "rx_sz_jumbo", .offset = 0x0f },28	{ .name = "rx_pause", .offset = 0x10 },29	{ .name = "rx_control", .offset = 0x11 },30	{ .name = "rx_long", .offset = 0x12 },31	{ .name = "rx_cat_drop", .offset = 0x13 },32	{ .name = "rx_red_prio_0", .offset = 0x14 },33	{ .name = "rx_red_prio_1", .offset = 0x15 },34	{ .name = "rx_red_prio_2", .offset = 0x16 },35	{ .name = "rx_red_prio_3", .offset = 0x17 },36	{ .name = "rx_red_prio_4", .offset = 0x18 },37	{ .name = "rx_red_prio_5", .offset = 0x19 },38	{ .name = "rx_red_prio_6", .offset = 0x1a },39	{ .name = "rx_red_prio_7", .offset = 0x1b },40	{ .name = "rx_yellow_prio_0", .offset = 0x1c },41	{ .name = "rx_yellow_prio_1", .offset = 0x1d },42	{ .name = "rx_yellow_prio_2", .offset = 0x1e },43	{ .name = "rx_yellow_prio_3", .offset = 0x1f },44	{ .name = "rx_yellow_prio_4", .offset = 0x20 },45	{ .name = "rx_yellow_prio_5", .offset = 0x21 },46	{ .name = "rx_yellow_prio_6", .offset = 0x22 },47	{ .name = "rx_yellow_prio_7", .offset = 0x23 },48	{ .name = "rx_green_prio_0", .offset = 0x24 },49	{ .name = "rx_green_prio_1", .offset = 0x25 },50	{ .name = "rx_green_prio_2", .offset = 0x26 },51	{ .name = "rx_green_prio_3", .offset = 0x27 },52	{ .name = "rx_green_prio_4", .offset = 0x28 },53	{ .name = "rx_green_prio_5", .offset = 0x29 },54	{ .name = "rx_green_prio_6", .offset = 0x2a },55	{ .name = "rx_green_prio_7", .offset = 0x2b },56	{ .name = "rx_assembly_err", .offset = 0x2c },57	{ .name = "rx_smd_err", .offset = 0x2d },58	{ .name = "rx_assembly_ok", .offset = 0x2e },59	{ .name = "rx_merge_frag", .offset = 0x2f },60	{ .name = "rx_pmac_octets", .offset = 0x30, },61	{ .name = "rx_pmac_unicast", .offset = 0x31, },62	{ .name = "rx_pmac_multicast", .offset = 0x32 },63	{ .name = "rx_pmac_broadcast", .offset = 0x33 },64	{ .name = "rx_pmac_short", .offset = 0x34 },65	{ .name = "rx_pmac_frag", .offset = 0x35 },66	{ .name = "rx_pmac_jabber", .offset = 0x36 },67	{ .name = "rx_pmac_crc", .offset = 0x37 },68	{ .name = "rx_pmac_symbol_err", .offset = 0x38 },69	{ .name = "rx_pmac_sz_64", .offset = 0x39 },70	{ .name = "rx_pmac_sz_65_127", .offset = 0x3a },71	{ .name = "rx_pmac_sz_128_255", .offset = 0x3b },72	{ .name = "rx_pmac_sz_256_511", .offset = 0x3c },73	{ .name = "rx_pmac_sz_512_1023", .offset = 0x3d },74	{ .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },75	{ .name = "rx_pmac_sz_jumbo", .offset = 0x3f },76	{ .name = "rx_pmac_pause", .offset = 0x40 },77	{ .name = "rx_pmac_control", .offset = 0x41 },78	{ .name = "rx_pmac_long", .offset = 0x42 },79 80	{ .name = "tx_octets", .offset = 0x80, },81	{ .name = "tx_unicast", .offset = 0x81, },82	{ .name = "tx_multicast", .offset = 0x82 },83	{ .name = "tx_broadcast", .offset = 0x83 },84	{ .name = "tx_col", .offset = 0x84 },85	{ .name = "tx_drop", .offset = 0x85 },86	{ .name = "tx_pause", .offset = 0x86 },87	{ .name = "tx_sz_64", .offset = 0x87 },88	{ .name = "tx_sz_65_127", .offset = 0x88 },89	{ .name = "tx_sz_128_255", .offset = 0x89 },90	{ .name = "tx_sz_256_511", .offset = 0x8a },91	{ .name = "tx_sz_512_1023", .offset = 0x8b },92	{ .name = "tx_sz_1024_1526", .offset = 0x8c },93	{ .name = "tx_sz_jumbo", .offset = 0x8d },94	{ .name = "tx_yellow_prio_0", .offset = 0x8e },95	{ .name = "tx_yellow_prio_1", .offset = 0x8f },96	{ .name = "tx_yellow_prio_2", .offset = 0x90 },97	{ .name = "tx_yellow_prio_3", .offset = 0x91 },98	{ .name = "tx_yellow_prio_4", .offset = 0x92 },99	{ .name = "tx_yellow_prio_5", .offset = 0x93 },100	{ .name = "tx_yellow_prio_6", .offset = 0x94 },101	{ .name = "tx_yellow_prio_7", .offset = 0x95 },102	{ .name = "tx_green_prio_0", .offset = 0x96 },103	{ .name = "tx_green_prio_1", .offset = 0x97 },104	{ .name = "tx_green_prio_2", .offset = 0x98 },105	{ .name = "tx_green_prio_3", .offset = 0x99 },106	{ .name = "tx_green_prio_4", .offset = 0x9a },107	{ .name = "tx_green_prio_5", .offset = 0x9b },108	{ .name = "tx_green_prio_6", .offset = 0x9c },109	{ .name = "tx_green_prio_7", .offset = 0x9d },110	{ .name = "tx_aged", .offset = 0x9e },111	{ .name = "tx_llct", .offset = 0x9f },112	{ .name = "tx_ct", .offset = 0xa0 },113	{ .name = "tx_mm_hold", .offset = 0xa1 },114	{ .name = "tx_merge_frag", .offset = 0xa2 },115	{ .name = "tx_pmac_octets", .offset = 0xa3, },116	{ .name = "tx_pmac_unicast", .offset = 0xa4, },117	{ .name = "tx_pmac_multicast", .offset = 0xa5 },118	{ .name = "tx_pmac_broadcast", .offset = 0xa6 },119	{ .name = "tx_pmac_pause", .offset = 0xa7 },120	{ .name = "tx_pmac_sz_64", .offset = 0xa8 },121	{ .name = "tx_pmac_sz_65_127", .offset = 0xa9 },122	{ .name = "tx_pmac_sz_128_255", .offset = 0xaa },123	{ .name = "tx_pmac_sz_256_511", .offset = 0xab },124	{ .name = "tx_pmac_sz_512_1023", .offset = 0xac },125	{ .name = "tx_pmac_sz_1024_1526", .offset = 0xad },126	{ .name = "tx_pmac_sz_jumbo", .offset = 0xae },127 128	{ .name = "dr_local", .offset = 0x100 },129	{ .name = "dr_tail", .offset = 0x101 },130	{ .name = "dr_yellow_prio_0", .offset = 0x102 },131	{ .name = "dr_yellow_prio_1", .offset = 0x103 },132	{ .name = "dr_yellow_prio_2", .offset = 0x104 },133	{ .name = "dr_yellow_prio_3", .offset = 0x105 },134	{ .name = "dr_yellow_prio_4", .offset = 0x106 },135	{ .name = "dr_yellow_prio_5", .offset = 0x107 },136	{ .name = "dr_yellow_prio_6", .offset = 0x108 },137	{ .name = "dr_yellow_prio_7", .offset = 0x109 },138	{ .name = "dr_green_prio_0", .offset = 0x10a },139	{ .name = "dr_green_prio_1", .offset = 0x10b },140	{ .name = "dr_green_prio_2", .offset = 0x10c },141	{ .name = "dr_green_prio_3", .offset = 0x10d },142	{ .name = "dr_green_prio_4", .offset = 0x10e },143	{ .name = "dr_green_prio_5", .offset = 0x10f },144	{ .name = "dr_green_prio_6", .offset = 0x110 },145	{ .name = "dr_green_prio_7", .offset = 0x111 },146};147 148/* The following numbers are indexes into lan966x_stats_layout[] */149#define SYS_COUNT_RX_OCT		  0150#define SYS_COUNT_RX_UC			  1151#define SYS_COUNT_RX_MC			  2152#define SYS_COUNT_RX_BC			  3153#define SYS_COUNT_RX_SHORT		  4154#define SYS_COUNT_RX_FRAG		  5155#define SYS_COUNT_RX_JABBER		  6156#define SYS_COUNT_RX_CRC		  7157#define SYS_COUNT_RX_SYMBOL_ERR		  8158#define SYS_COUNT_RX_SZ_64		  9159#define SYS_COUNT_RX_SZ_65_127		 10160#define SYS_COUNT_RX_SZ_128_255		 11161#define SYS_COUNT_RX_SZ_256_511		 12162#define SYS_COUNT_RX_SZ_512_1023	 13163#define SYS_COUNT_RX_SZ_1024_1526	 14164#define SYS_COUNT_RX_SZ_JUMBO		 15165#define SYS_COUNT_RX_PAUSE		 16166#define SYS_COUNT_RX_CONTROL		 17167#define SYS_COUNT_RX_LONG		 18168#define SYS_COUNT_RX_CAT_DROP		 19169#define SYS_COUNT_RX_RED_PRIO_0		 20170#define SYS_COUNT_RX_RED_PRIO_1		 21171#define SYS_COUNT_RX_RED_PRIO_2		 22172#define SYS_COUNT_RX_RED_PRIO_3		 23173#define SYS_COUNT_RX_RED_PRIO_4		 24174#define SYS_COUNT_RX_RED_PRIO_5		 25175#define SYS_COUNT_RX_RED_PRIO_6		 26176#define SYS_COUNT_RX_RED_PRIO_7		 27177#define SYS_COUNT_RX_YELLOW_PRIO_0	 28178#define SYS_COUNT_RX_YELLOW_PRIO_1	 29179#define SYS_COUNT_RX_YELLOW_PRIO_2	 30180#define SYS_COUNT_RX_YELLOW_PRIO_3	 31181#define SYS_COUNT_RX_YELLOW_PRIO_4	 32182#define SYS_COUNT_RX_YELLOW_PRIO_5	 33183#define SYS_COUNT_RX_YELLOW_PRIO_6	 34184#define SYS_COUNT_RX_YELLOW_PRIO_7	 35185#define SYS_COUNT_RX_GREEN_PRIO_0	 36186#define SYS_COUNT_RX_GREEN_PRIO_1	 37187#define SYS_COUNT_RX_GREEN_PRIO_2	 38188#define SYS_COUNT_RX_GREEN_PRIO_3	 39189#define SYS_COUNT_RX_GREEN_PRIO_4	 40190#define SYS_COUNT_RX_GREEN_PRIO_5	 41191#define SYS_COUNT_RX_GREEN_PRIO_6	 42192#define SYS_COUNT_RX_GREEN_PRIO_7	 43193#define SYS_COUNT_RX_ASSEMBLY_ERR	 44194#define SYS_COUNT_RX_SMD_ERR		 45195#define SYS_COUNT_RX_ASSEMBLY_OK	 46196#define SYS_COUNT_RX_MERGE_FRAG		 47197#define SYS_COUNT_RX_PMAC_OCT		 48198#define SYS_COUNT_RX_PMAC_UC		 49199#define SYS_COUNT_RX_PMAC_MC		 50200#define SYS_COUNT_RX_PMAC_BC		 51201#define SYS_COUNT_RX_PMAC_SHORT		 52202#define SYS_COUNT_RX_PMAC_FRAG		 53203#define SYS_COUNT_RX_PMAC_JABBER	 54204#define SYS_COUNT_RX_PMAC_CRC		 55205#define SYS_COUNT_RX_PMAC_SYMBOL_ERR	 56206#define SYS_COUNT_RX_PMAC_SZ_64		 57207#define SYS_COUNT_RX_PMAC_SZ_65_127	 58208#define SYS_COUNT_RX_PMAC_SZ_128_255	 59209#define SYS_COUNT_RX_PMAC_SZ_256_511	 60210#define SYS_COUNT_RX_PMAC_SZ_512_1023	 61211#define SYS_COUNT_RX_PMAC_SZ_1024_1526	 62212#define SYS_COUNT_RX_PMAC_SZ_JUMBO	 63213#define SYS_COUNT_RX_PMAC_PAUSE		 64214#define SYS_COUNT_RX_PMAC_CONTROL	 65215#define SYS_COUNT_RX_PMAC_LONG		 66216 217#define SYS_COUNT_TX_OCT		 67218#define SYS_COUNT_TX_UC			 68219#define SYS_COUNT_TX_MC			 69220#define SYS_COUNT_TX_BC			 70221#define SYS_COUNT_TX_COL		 71222#define SYS_COUNT_TX_DROP		 72223#define SYS_COUNT_TX_PAUSE		 73224#define SYS_COUNT_TX_SZ_64		 74225#define SYS_COUNT_TX_SZ_65_127		 75226#define SYS_COUNT_TX_SZ_128_255		 76227#define SYS_COUNT_TX_SZ_256_511		 77228#define SYS_COUNT_TX_SZ_512_1023	 78229#define SYS_COUNT_TX_SZ_1024_1526	 79230#define SYS_COUNT_TX_SZ_JUMBO		 80231#define SYS_COUNT_TX_YELLOW_PRIO_0	 81232#define SYS_COUNT_TX_YELLOW_PRIO_1	 82233#define SYS_COUNT_TX_YELLOW_PRIO_2	 83234#define SYS_COUNT_TX_YELLOW_PRIO_3	 84235#define SYS_COUNT_TX_YELLOW_PRIO_4	 85236#define SYS_COUNT_TX_YELLOW_PRIO_5	 86237#define SYS_COUNT_TX_YELLOW_PRIO_6	 87238#define SYS_COUNT_TX_YELLOW_PRIO_7	 88239#define SYS_COUNT_TX_GREEN_PRIO_0	 89240#define SYS_COUNT_TX_GREEN_PRIO_1	 90241#define SYS_COUNT_TX_GREEN_PRIO_2	 91242#define SYS_COUNT_TX_GREEN_PRIO_3	 92243#define SYS_COUNT_TX_GREEN_PRIO_4	 93244#define SYS_COUNT_TX_GREEN_PRIO_5	 94245#define SYS_COUNT_TX_GREEN_PRIO_6	 95246#define SYS_COUNT_TX_GREEN_PRIO_7	 96247#define SYS_COUNT_TX_AGED		 97248#define SYS_COUNT_TX_LLCT		 98249#define SYS_COUNT_TX_CT			 99250#define SYS_COUNT_TX_MM_HOLD		100251#define SYS_COUNT_TX_MERGE_FRAG		101252#define SYS_COUNT_TX_PMAC_OCT		102253#define SYS_COUNT_TX_PMAC_UC		103254#define SYS_COUNT_TX_PMAC_MC		104255#define SYS_COUNT_TX_PMAC_BC		105256#define SYS_COUNT_TX_PMAC_PAUSE		106257#define SYS_COUNT_TX_PMAC_SZ_64		107258#define SYS_COUNT_TX_PMAC_SZ_65_127	108259#define SYS_COUNT_TX_PMAC_SZ_128_255	109260#define SYS_COUNT_TX_PMAC_SZ_256_511	110261#define SYS_COUNT_TX_PMAC_SZ_512_1023	111262#define SYS_COUNT_TX_PMAC_SZ_1024_1526	112263#define SYS_COUNT_TX_PMAC_SZ_JUMBO	113264 265#define SYS_COUNT_DR_LOCAL		114266#define SYS_COUNT_DR_TAIL		115267#define SYS_COUNT_DR_YELLOW_PRIO_0	116268#define SYS_COUNT_DR_YELLOW_PRIO_1	117269#define SYS_COUNT_DR_YELLOW_PRIO_2	118270#define SYS_COUNT_DR_YELLOW_PRIO_3	119271#define SYS_COUNT_DR_YELLOW_PRIO_4	120272#define SYS_COUNT_DR_YELLOW_PRIO_5	121273#define SYS_COUNT_DR_YELLOW_PRIO_6	122274#define SYS_COUNT_DR_YELLOW_PRIO_7	123275#define SYS_COUNT_DR_GREEN_PRIO_0	124276#define SYS_COUNT_DR_GREEN_PRIO_1	125277#define SYS_COUNT_DR_GREEN_PRIO_2	126278#define SYS_COUNT_DR_GREEN_PRIO_3	127279#define SYS_COUNT_DR_GREEN_PRIO_4	128280#define SYS_COUNT_DR_GREEN_PRIO_5	129281#define SYS_COUNT_DR_GREEN_PRIO_6	130282#define SYS_COUNT_DR_GREEN_PRIO_7	131283 284/* Add a possibly wrapping 32 bit value to a 64 bit counter */285static void lan966x_add_cnt(u64 *cnt, u32 val)286{287	if (val < (*cnt & U32_MAX))288		*cnt += (u64)1 << 32; /* value has wrapped */289 290	*cnt = (*cnt & ~(u64)U32_MAX) + val;291}292 293static void lan966x_stats_update(struct lan966x *lan966x)294{295	int i, j;296 297	mutex_lock(&lan966x->stats_lock);298 299	for (i = 0; i < lan966x->num_phys_ports; i++) {300		uint idx = i * lan966x->num_stats;301 302		lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),303		       lan966x, SYS_STAT_CFG);304 305		for (j = 0; j < lan966x->num_stats; j++) {306			u32 offset = lan966x->stats_layout[j].offset;307 308			lan966x_add_cnt(&lan966x->stats[idx++],309					lan_rd(lan966x, SYS_CNT(offset)));310		}311	}312 313	mutex_unlock(&lan966x->stats_lock);314}315 316static int lan966x_get_sset_count(struct net_device *dev, int sset)317{318	struct lan966x_port *port = netdev_priv(dev);319	struct lan966x *lan966x = port->lan966x;320 321	if (sset != ETH_SS_STATS)322		return -EOPNOTSUPP;323 324	return lan966x->num_stats;325}326 327static void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)328{329	struct lan966x_port *port = netdev_priv(netdev);330	struct lan966x *lan966x = port->lan966x;331	int i;332 333	if (sset != ETH_SS_STATS)334		return;335 336	for (i = 0; i < lan966x->num_stats; i++)337		memcpy(data + i * ETH_GSTRING_LEN,338		       lan966x->stats_layout[i].name, ETH_GSTRING_LEN);339}340 341static void lan966x_get_ethtool_stats(struct net_device *dev,342				      struct ethtool_stats *stats, u64 *data)343{344	struct lan966x_port *port = netdev_priv(dev);345	struct lan966x *lan966x = port->lan966x;346	int i;347 348	/* check and update now */349	lan966x_stats_update(lan966x);350 351	/* Copy all counters */352	for (i = 0; i < lan966x->num_stats; i++)353		*data++ = lan966x->stats[port->chip_port *354					 lan966x->num_stats + i];355}356 357static void lan966x_get_eth_mac_stats(struct net_device *dev,358				      struct ethtool_eth_mac_stats *mac_stats)359{360	struct lan966x_port *port = netdev_priv(dev);361	struct lan966x *lan966x = port->lan966x;362	u32 idx;363 364	lan966x_stats_update(lan966x);365 366	idx = port->chip_port * lan966x->num_stats;367 368	mutex_lock(&lan966x->stats_lock);369 370	mac_stats->FramesTransmittedOK =371		lan966x->stats[idx + SYS_COUNT_TX_UC] +372		lan966x->stats[idx + SYS_COUNT_TX_MC] +373		lan966x->stats[idx + SYS_COUNT_TX_BC] +374		lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +375		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +376		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];377	mac_stats->SingleCollisionFrames =378		lan966x->stats[idx + SYS_COUNT_TX_COL];379	mac_stats->FramesReceivedOK =380		lan966x->stats[idx + SYS_COUNT_RX_UC] +381		lan966x->stats[idx + SYS_COUNT_RX_MC] +382		lan966x->stats[idx + SYS_COUNT_RX_BC];383	mac_stats->FrameCheckSequenceErrors =384		lan966x->stats[idx + SYS_COUNT_RX_CRC] +385		lan966x->stats[idx + SYS_COUNT_RX_CRC];386	mac_stats->OctetsTransmittedOK =387		lan966x->stats[idx + SYS_COUNT_TX_OCT] +388		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];389	mac_stats->FramesWithDeferredXmissions =390		lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];391	mac_stats->OctetsReceivedOK =392		lan966x->stats[idx + SYS_COUNT_RX_OCT];393	mac_stats->MulticastFramesXmittedOK =394		lan966x->stats[idx + SYS_COUNT_TX_MC] +395		lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];396	mac_stats->BroadcastFramesXmittedOK =397		lan966x->stats[idx + SYS_COUNT_TX_BC] +398		lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];399	mac_stats->MulticastFramesReceivedOK =400		lan966x->stats[idx + SYS_COUNT_RX_MC];401	mac_stats->BroadcastFramesReceivedOK =402		lan966x->stats[idx + SYS_COUNT_RX_BC];403	mac_stats->InRangeLengthErrors =404		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +405		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +406		lan966x->stats[idx + SYS_COUNT_RX_CRC] +407		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +408		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +409		lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];410	mac_stats->OutOfRangeLengthField =411		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +412		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +413		lan966x->stats[idx + SYS_COUNT_RX_LONG] +414		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];415	mac_stats->FrameTooLongErrors =416		lan966x->stats[idx + SYS_COUNT_RX_LONG] +417		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];418 419	mutex_unlock(&lan966x->stats_lock);420}421 422static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {423	{    0,    64 },424	{   65,   127 },425	{  128,   255 },426	{  256,   511 },427	{  512,  1023 },428	{ 1024,  1518 },429	{ 1519, 10239 },430	{}431};432 433static void lan966x_get_eth_rmon_stats(struct net_device *dev,434				       struct ethtool_rmon_stats *rmon_stats,435				       const struct ethtool_rmon_hist_range **ranges)436{437	struct lan966x_port *port = netdev_priv(dev);438	struct lan966x *lan966x = port->lan966x;439	u32 idx;440 441	lan966x_stats_update(lan966x);442 443	idx = port->chip_port * lan966x->num_stats;444 445	mutex_lock(&lan966x->stats_lock);446 447	rmon_stats->undersize_pkts =448		lan966x->stats[idx + SYS_COUNT_RX_SHORT] +449		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];450	rmon_stats->oversize_pkts =451		lan966x->stats[idx + SYS_COUNT_RX_LONG] +452		lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];453	rmon_stats->fragments =454		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +455		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];456	rmon_stats->jabbers =457		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +458		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];459	rmon_stats->hist[0] =460		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +461		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];462	rmon_stats->hist[1] =463		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +464		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];465	rmon_stats->hist[2] =466		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +467		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];468	rmon_stats->hist[3] =469		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +470		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];471	rmon_stats->hist[4] =472		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +473		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];474	rmon_stats->hist[5] =475		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +476		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];477	rmon_stats->hist[6] =478		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +479		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];480 481	rmon_stats->hist_tx[0] =482		lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +483		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];484	rmon_stats->hist_tx[1] =485		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +486		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];487	rmon_stats->hist_tx[2] =488		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +489		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];490	rmon_stats->hist_tx[3] =491		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +492		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];493	rmon_stats->hist_tx[4] =494		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +495		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];496	rmon_stats->hist_tx[5] =497		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +498		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];499	rmon_stats->hist_tx[6] =500		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +501		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];502 503	mutex_unlock(&lan966x->stats_lock);504 505	*ranges = lan966x_rmon_ranges;506}507 508static int lan966x_get_link_ksettings(struct net_device *ndev,509				      struct ethtool_link_ksettings *cmd)510{511	struct lan966x_port *port = netdev_priv(ndev);512 513	return phylink_ethtool_ksettings_get(port->phylink, cmd);514}515 516static int lan966x_set_link_ksettings(struct net_device *ndev,517				      const struct ethtool_link_ksettings *cmd)518{519	struct lan966x_port *port = netdev_priv(ndev);520 521	return phylink_ethtool_ksettings_set(port->phylink, cmd);522}523 524static void lan966x_get_pauseparam(struct net_device *dev,525				   struct ethtool_pauseparam *pause)526{527	struct lan966x_port *port = netdev_priv(dev);528 529	phylink_ethtool_get_pauseparam(port->phylink, pause);530}531 532static int lan966x_set_pauseparam(struct net_device *dev,533				  struct ethtool_pauseparam *pause)534{535	struct lan966x_port *port = netdev_priv(dev);536 537	return phylink_ethtool_set_pauseparam(port->phylink, pause);538}539 540static int lan966x_get_ts_info(struct net_device *dev,541			       struct kernel_ethtool_ts_info *info)542{543	struct lan966x_port *port = netdev_priv(dev);544	struct lan966x *lan966x = port->lan966x;545	struct lan966x_phc *phc;546 547	if (!lan966x->ptp)548		return ethtool_op_get_ts_info(dev, info);549 550	phc = &lan966x->phc[LAN966X_PHC_PORT];551 552	if (phc->clock) {553		info->phc_index = ptp_clock_index(phc->clock);554	} else {555		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;556		return 0;557	}558	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |559				 SOF_TIMESTAMPING_TX_HARDWARE |560				 SOF_TIMESTAMPING_RX_HARDWARE |561				 SOF_TIMESTAMPING_RAW_HARDWARE;562	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |563			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);564	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |565			   BIT(HWTSTAMP_FILTER_ALL);566 567	return 0;568}569 570const struct ethtool_ops lan966x_ethtool_ops = {571	.get_link_ksettings     = lan966x_get_link_ksettings,572	.set_link_ksettings     = lan966x_set_link_ksettings,573	.get_pauseparam		= lan966x_get_pauseparam,574	.set_pauseparam		= lan966x_set_pauseparam,575	.get_sset_count		= lan966x_get_sset_count,576	.get_strings		= lan966x_get_strings,577	.get_ethtool_stats	= lan966x_get_ethtool_stats,578	.get_eth_mac_stats      = lan966x_get_eth_mac_stats,579	.get_rmon_stats		= lan966x_get_eth_rmon_stats,580	.get_link		= ethtool_op_get_link,581	.get_ts_info		= lan966x_get_ts_info,582};583 584static void lan966x_check_stats_work(struct work_struct *work)585{586	struct delayed_work *del_work = to_delayed_work(work);587	struct lan966x *lan966x = container_of(del_work, struct lan966x,588					       stats_work);589 590	lan966x_stats_update(lan966x);591 592	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,593			   LAN966X_STATS_CHECK_DELAY);594}595 596void lan966x_stats_get(struct net_device *dev,597		       struct rtnl_link_stats64 *stats)598{599	struct lan966x_port *port = netdev_priv(dev);600	struct lan966x *lan966x = port->lan966x;601	u32 idx;602	int i;603 604	idx = port->chip_port * lan966x->num_stats;605 606	mutex_lock(&lan966x->stats_lock);607 608	stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +609		lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];610 611	stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +612		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +613		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +614		lan966x->stats[idx + SYS_COUNT_RX_CRC] +615		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +616		lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +617		lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +618		lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +619		lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +620		lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +621		lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +622		lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +623		lan966x->stats[idx + SYS_COUNT_RX_LONG] +624		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +625		lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +626		lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +627		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +628		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +629		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +630		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +631		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +632		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +633		lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];634 635	stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +636		lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];637 638	stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +639		lan966x->stats[idx + SYS_COUNT_RX_FRAG] +640		lan966x->stats[idx + SYS_COUNT_RX_JABBER] +641		lan966x->stats[idx + SYS_COUNT_RX_CRC] +642		lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +643		lan966x->stats[idx + SYS_COUNT_RX_LONG];644 645	stats->rx_dropped = dev->stats.rx_dropped +646		lan966x->stats[idx + SYS_COUNT_RX_LONG] +647		lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +648		lan966x->stats[idx + SYS_COUNT_DR_TAIL] +649		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +650		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +651		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +652		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +653		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +654		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +655		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +656		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];657 658	for (i = 0; i < LAN966X_NUM_TC; i++) {659		stats->rx_dropped +=660			(lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +661			 lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);662	}663 664	/* Get Tx stats */665	stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +666		lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];667 668	stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +669		lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +670		lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +671		lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +672		lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +673		lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +674		lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +675		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +676		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +677		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +678		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +679		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +680		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +681		lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];682 683	stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +684		lan966x->stats[idx + SYS_COUNT_TX_AGED];685 686	stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];687 688	mutex_unlock(&lan966x->stats_lock);689}690 691int lan966x_stats_init(struct lan966x *lan966x)692{693	char queue_name[32];694 695	lan966x->stats_layout = lan966x_stats_layout;696	lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);697	lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *698				      lan966x->num_stats,699				      sizeof(u64), GFP_KERNEL);700	if (!lan966x->stats)701		return -ENOMEM;702 703	/* Init stats worker */704	mutex_init(&lan966x->stats_lock);705	snprintf(queue_name, sizeof(queue_name), "%s-stats",706		 dev_name(lan966x->dev));707	lan966x->stats_queue = create_singlethread_workqueue(queue_name);708	if (!lan966x->stats_queue)709		return -ENOMEM;710 711	INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);712	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,713			   LAN966X_STATS_CHECK_DELAY);714 715	return 0;716}717