1// SPDX-License-Identifier: GPL-2.0+
2/* Microchip Sparx5 Switch driver
3 *
4 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
5 */
6
7#include <linux/ethtool.h>
8
9#include "sparx5_main_regs.h"
10#include "sparx5_main.h"
11#include "sparx5_port.h"
12
13/* Index of ANA_AC port counters */
14#define SPX5_PORT_POLICER_DROPS 0
15
16/* Add a potentially wrapping 32 bit value to a 64 bit counter */
17static void sparx5_update_counter(u64 *cnt, u32 val)
18{
19	if (val < (*cnt & U32_MAX))
20		*cnt += (u64)1 << 32; /* value has wrapped */
21	*cnt = (*cnt & ~(u64)U32_MAX) + val;
22}
23
24enum sparx5_stats_entry {
25	spx5_stats_rx_symbol_err_cnt = 0,
26	spx5_stats_pmac_rx_symbol_err_cnt = 1,
27	spx5_stats_tx_uc_cnt = 2,
28	spx5_stats_pmac_tx_uc_cnt = 3,
29	spx5_stats_tx_mc_cnt = 4,
30	spx5_stats_tx_bc_cnt = 5,
31	spx5_stats_tx_backoff1_cnt = 6,
32	spx5_stats_tx_multi_coll_cnt = 7,
33	spx5_stats_rx_uc_cnt = 8,
34	spx5_stats_pmac_rx_uc_cnt = 9,
35	spx5_stats_rx_mc_cnt = 10,
36	spx5_stats_rx_bc_cnt = 11,
37	spx5_stats_rx_crc_err_cnt = 12,
38	spx5_stats_pmac_rx_crc_err_cnt = 13,
39	spx5_stats_rx_alignment_lost_cnt = 14,
40	spx5_stats_pmac_rx_alignment_lost_cnt = 15,
41	spx5_stats_tx_ok_bytes_cnt = 16,
42	spx5_stats_pmac_tx_ok_bytes_cnt = 17,
43	spx5_stats_tx_defer_cnt = 18,
44	spx5_stats_tx_late_coll_cnt = 19,
45	spx5_stats_tx_xcoll_cnt = 20,
46	spx5_stats_tx_csense_cnt = 21,
47	spx5_stats_rx_ok_bytes_cnt = 22,
48	spx5_stats_pmac_rx_ok_bytes_cnt = 23,
49	spx5_stats_pmac_tx_mc_cnt = 24,
50	spx5_stats_pmac_tx_bc_cnt = 25,
51	spx5_stats_tx_xdefer_cnt = 26,
52	spx5_stats_pmac_rx_mc_cnt = 27,
53	spx5_stats_pmac_rx_bc_cnt = 28,
54	spx5_stats_rx_in_range_len_err_cnt = 29,
55	spx5_stats_pmac_rx_in_range_len_err_cnt = 30,
56	spx5_stats_rx_out_of_range_len_err_cnt = 31,
57	spx5_stats_pmac_rx_out_of_range_len_err_cnt = 32,
58	spx5_stats_rx_oversize_cnt = 33,
59	spx5_stats_pmac_rx_oversize_cnt = 34,
60	spx5_stats_tx_pause_cnt = 35,
61	spx5_stats_pmac_tx_pause_cnt = 36,
62	spx5_stats_rx_pause_cnt = 37,
63	spx5_stats_pmac_rx_pause_cnt = 38,
64	spx5_stats_rx_unsup_opcode_cnt = 39,
65	spx5_stats_pmac_rx_unsup_opcode_cnt = 40,
66	spx5_stats_rx_undersize_cnt = 41,
67	spx5_stats_pmac_rx_undersize_cnt = 42,
68	spx5_stats_rx_fragments_cnt = 43,
69	spx5_stats_pmac_rx_fragments_cnt = 44,
70	spx5_stats_rx_jabbers_cnt = 45,
71	spx5_stats_pmac_rx_jabbers_cnt = 46,
72	spx5_stats_rx_size64_cnt = 47,
73	spx5_stats_pmac_rx_size64_cnt = 48,
74	spx5_stats_rx_size65to127_cnt = 49,
75	spx5_stats_pmac_rx_size65to127_cnt = 50,
76	spx5_stats_rx_size128to255_cnt = 51,
77	spx5_stats_pmac_rx_size128to255_cnt = 52,
78	spx5_stats_rx_size256to511_cnt = 53,
79	spx5_stats_pmac_rx_size256to511_cnt = 54,
80	spx5_stats_rx_size512to1023_cnt = 55,
81	spx5_stats_pmac_rx_size512to1023_cnt = 56,
82	spx5_stats_rx_size1024to1518_cnt = 57,
83	spx5_stats_pmac_rx_size1024to1518_cnt = 58,
84	spx5_stats_rx_size1519tomax_cnt = 59,
85	spx5_stats_pmac_rx_size1519tomax_cnt = 60,
86	spx5_stats_tx_size64_cnt = 61,
87	spx5_stats_pmac_tx_size64_cnt = 62,
88	spx5_stats_tx_size65to127_cnt = 63,
89	spx5_stats_pmac_tx_size65to127_cnt = 64,
90	spx5_stats_tx_size128to255_cnt = 65,
91	spx5_stats_pmac_tx_size128to255_cnt = 66,
92	spx5_stats_tx_size256to511_cnt = 67,
93	spx5_stats_pmac_tx_size256to511_cnt = 68,
94	spx5_stats_tx_size512to1023_cnt = 69,
95	spx5_stats_pmac_tx_size512to1023_cnt = 70,
96	spx5_stats_tx_size1024to1518_cnt = 71,
97	spx5_stats_pmac_tx_size1024to1518_cnt = 72,
98	spx5_stats_tx_size1519tomax_cnt = 73,
99	spx5_stats_pmac_tx_size1519tomax_cnt = 74,
100	spx5_stats_mm_rx_assembly_err_cnt = 75,
101	spx5_stats_mm_rx_assembly_ok_cnt = 76,
102	spx5_stats_mm_rx_merge_frag_cnt = 77,
103	spx5_stats_mm_rx_smd_err_cnt = 78,
104	spx5_stats_mm_tx_pfragment_cnt = 79,
105	spx5_stats_rx_bad_bytes_cnt = 80,
106	spx5_stats_pmac_rx_bad_bytes_cnt = 81,
107	spx5_stats_rx_in_bytes_cnt = 82,
108	spx5_stats_rx_ipg_shrink_cnt = 83,
109	spx5_stats_rx_sync_lost_err_cnt = 84,
110	spx5_stats_rx_tagged_frms_cnt = 85,
111	spx5_stats_rx_untagged_frms_cnt = 86,
112	spx5_stats_tx_out_bytes_cnt = 87,
113	spx5_stats_tx_tagged_frms_cnt = 88,
114	spx5_stats_tx_untagged_frms_cnt = 89,
115	spx5_stats_rx_hih_cksm_err_cnt = 90,
116	spx5_stats_pmac_rx_hih_cksm_err_cnt = 91,
117	spx5_stats_rx_xgmii_prot_err_cnt = 92,
118	spx5_stats_pmac_rx_xgmii_prot_err_cnt = 93,
119	spx5_stats_ana_ac_port_stat_lsb_cnt = 94,
120	spx5_stats_green_p0_rx_fwd = 95,
121	spx5_stats_green_p0_rx_port_drop = 111,
122	spx5_stats_green_p0_tx_port = 127,
123	spx5_stats_rx_local_drop = 143,
124	spx5_stats_tx_local_drop = 144,
125	spx5_stats_count = 145,
126};
127
128static const char *const sparx5_stats_layout[] = {
129	"mm_rx_assembly_err_cnt",
130	"mm_rx_assembly_ok_cnt",
131	"mm_rx_merge_frag_cnt",
132	"mm_rx_smd_err_cnt",
133	"mm_tx_pfragment_cnt",
134	"rx_bad_bytes_cnt",
135	"pmac_rx_bad_bytes_cnt",
136	"rx_in_bytes_cnt",
137	"rx_ipg_shrink_cnt",
138	"rx_sync_lost_err_cnt",
139	"rx_tagged_frms_cnt",
140	"rx_untagged_frms_cnt",
141	"tx_out_bytes_cnt",
142	"tx_tagged_frms_cnt",
143	"tx_untagged_frms_cnt",
144	"rx_hih_cksm_err_cnt",
145	"pmac_rx_hih_cksm_err_cnt",
146	"rx_xgmii_prot_err_cnt",
147	"pmac_rx_xgmii_prot_err_cnt",
148	"rx_port_policer_drop",
149	"rx_fwd_green_p0",
150	"rx_fwd_green_p1",
151	"rx_fwd_green_p2",
152	"rx_fwd_green_p3",
153	"rx_fwd_green_p4",
154	"rx_fwd_green_p5",
155	"rx_fwd_green_p6",
156	"rx_fwd_green_p7",
157	"rx_fwd_yellow_p0",
158	"rx_fwd_yellow_p1",
159	"rx_fwd_yellow_p2",
160	"rx_fwd_yellow_p3",
161	"rx_fwd_yellow_p4",
162	"rx_fwd_yellow_p5",
163	"rx_fwd_yellow_p6",
164	"rx_fwd_yellow_p7",
165	"rx_port_drop_green_p0",
166	"rx_port_drop_green_p1",
167	"rx_port_drop_green_p2",
168	"rx_port_drop_green_p3",
169	"rx_port_drop_green_p4",
170	"rx_port_drop_green_p5",
171	"rx_port_drop_green_p6",
172	"rx_port_drop_green_p7",
173	"rx_port_drop_yellow_p0",
174	"rx_port_drop_yellow_p1",
175	"rx_port_drop_yellow_p2",
176	"rx_port_drop_yellow_p3",
177	"rx_port_drop_yellow_p4",
178	"rx_port_drop_yellow_p5",
179	"rx_port_drop_yellow_p6",
180	"rx_port_drop_yellow_p7",
181	"tx_port_green_p0",
182	"tx_port_green_p1",
183	"tx_port_green_p2",
184	"tx_port_green_p3",
185	"tx_port_green_p4",
186	"tx_port_green_p5",
187	"tx_port_green_p6",
188	"tx_port_green_p7",
189	"tx_port_yellow_p0",
190	"tx_port_yellow_p1",
191	"tx_port_yellow_p2",
192	"tx_port_yellow_p3",
193	"tx_port_yellow_p4",
194	"tx_port_yellow_p5",
195	"tx_port_yellow_p6",
196	"tx_port_yellow_p7",
197	"rx_local_drop",
198	"tx_local_drop",
199};
200
201static void sparx5_get_queue_sys_stats(struct sparx5 *sparx5, int portno)
202{
203	u64 *portstats;
204	u64 *stats;
205	u32 addr;
206	int idx;
207
208	portstats = &sparx5->stats[portno * sparx5->num_stats];
209	mutex_lock(&sparx5->queue_stats_lock);
210	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno), sparx5, XQS_STAT_CFG);
211	addr = 0;
212	stats = &portstats[spx5_stats_green_p0_rx_fwd];
213	for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
214		sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
215	addr = 16;
216	stats = &portstats[spx5_stats_green_p0_rx_port_drop];
217	for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
218		sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
219	addr = 256;
220	stats = &portstats[spx5_stats_green_p0_tx_port];
221	for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
222		sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
223	sparx5_update_counter(&portstats[spx5_stats_rx_local_drop],
224			      spx5_rd(sparx5, XQS_CNT(32)));
225	sparx5_update_counter(&portstats[spx5_stats_tx_local_drop],
226			      spx5_rd(sparx5, XQS_CNT(272)));
227	mutex_unlock(&sparx5->queue_stats_lock);
228}
229
230static void sparx5_get_ana_ac_stats_stats(struct sparx5 *sparx5, int portno)
231{
232	u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
233
234	sparx5_update_counter(&portstats[spx5_stats_ana_ac_port_stat_lsb_cnt],
235			      spx5_rd(sparx5, ANA_AC_PORT_STAT_LSB_CNT(portno,
236								       SPX5_PORT_POLICER_DROPS)));
237}
238
239static void sparx5_get_dev_phy_stats(u64 *portstats, void __iomem *inst, u32
240				     tinst)
241{
242	sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
243			      spx5_inst_rd(inst,
244					   DEV5G_RX_SYMBOL_ERR_CNT(tinst)));
245	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
246			      spx5_inst_rd(inst,
247					   DEV5G_PMAC_RX_SYMBOL_ERR_CNT(tinst)));
248}
249
250static void sparx5_get_dev_mac_stats(u64 *portstats, void __iomem *inst, u32
251				     tinst)
252{
253	sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
254			      spx5_inst_rd(inst, DEV5G_TX_UC_CNT(tinst)));
255	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
256			      spx5_inst_rd(inst, DEV5G_PMAC_TX_UC_CNT(tinst)));
257	sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
258			      spx5_inst_rd(inst, DEV5G_TX_MC_CNT(tinst)));
259	sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
260			      spx5_inst_rd(inst, DEV5G_TX_BC_CNT(tinst)));
261	sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
262			      spx5_inst_rd(inst, DEV5G_RX_UC_CNT(tinst)));
263	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
264			      spx5_inst_rd(inst, DEV5G_PMAC_RX_UC_CNT(tinst)));
265	sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
266			      spx5_inst_rd(inst, DEV5G_RX_MC_CNT(tinst)));
267	sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
268			      spx5_inst_rd(inst, DEV5G_RX_BC_CNT(tinst)));
269	sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
270			      spx5_inst_rd(inst, DEV5G_RX_CRC_ERR_CNT(tinst)));
271	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
272			      spx5_inst_rd(inst,
273					   DEV5G_PMAC_RX_CRC_ERR_CNT(tinst)));
274	sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
275			      spx5_inst_rd(inst,
276					   DEV5G_RX_ALIGNMENT_LOST_CNT(tinst)));
277	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
278			      spx5_inst_rd(inst,
279					   DEV5G_PMAC_RX_ALIGNMENT_LOST_CNT(tinst)));
280	sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
281			      spx5_inst_rd(inst, DEV5G_TX_OK_BYTES_CNT(tinst)));
282	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
283			      spx5_inst_rd(inst,
284					   DEV5G_PMAC_TX_OK_BYTES_CNT(tinst)));
285	sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
286			      spx5_inst_rd(inst, DEV5G_RX_OK_BYTES_CNT(tinst)));
287	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
288			      spx5_inst_rd(inst,
289					   DEV5G_PMAC_RX_OK_BYTES_CNT(tinst)));
290	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
291			      spx5_inst_rd(inst, DEV5G_PMAC_TX_MC_CNT(tinst)));
292	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
293			      spx5_inst_rd(inst, DEV5G_PMAC_TX_BC_CNT(tinst)));
294	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
295			      spx5_inst_rd(inst, DEV5G_PMAC_RX_MC_CNT(tinst)));
296	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
297			      spx5_inst_rd(inst, DEV5G_PMAC_RX_BC_CNT(tinst)));
298	sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
299			      spx5_inst_rd(inst,
300					   DEV5G_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
301	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
302			      spx5_inst_rd(inst,
303					   DEV5G_PMAC_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
304	sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
305			      spx5_inst_rd(inst,
306					   DEV5G_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
307	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
308			      spx5_inst_rd(inst,
309					   DEV5G_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
310	sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
311			      spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
312	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
313			      spx5_inst_rd(inst,
314					   DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
315}
316
317static void sparx5_get_dev_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
318					  u32 tinst)
319{
320	sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
321			      spx5_inst_rd(inst, DEV5G_TX_PAUSE_CNT(tinst)));
322	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
323			      spx5_inst_rd(inst,
324					   DEV5G_PMAC_TX_PAUSE_CNT(tinst)));
325	sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
326			      spx5_inst_rd(inst, DEV5G_RX_PAUSE_CNT(tinst)));
327	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
328			      spx5_inst_rd(inst,
329					   DEV5G_PMAC_RX_PAUSE_CNT(tinst)));
330	sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
331			      spx5_inst_rd(inst,
332					   DEV5G_RX_UNSUP_OPCODE_CNT(tinst)));
333	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
334			      spx5_inst_rd(inst,
335					   DEV5G_PMAC_RX_UNSUP_OPCODE_CNT(tinst)));
336}
337
338static void sparx5_get_dev_rmon_stats(u64 *portstats, void __iomem *inst, u32
339				      tinst)
340{
341	sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
342			      spx5_inst_rd(inst,
343					   DEV5G_RX_UNDERSIZE_CNT(tinst)));
344	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
345			      spx5_inst_rd(inst,
346					   DEV5G_PMAC_RX_UNDERSIZE_CNT(tinst)));
347	sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
348			      spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
349	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
350			      spx5_inst_rd(inst,
351					   DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
352	sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
353			      spx5_inst_rd(inst,
354					   DEV5G_RX_FRAGMENTS_CNT(tinst)));
355	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
356			      spx5_inst_rd(inst,
357					   DEV5G_PMAC_RX_FRAGMENTS_CNT(tinst)));
358	sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
359			      spx5_inst_rd(inst, DEV5G_RX_JABBERS_CNT(tinst)));
360	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
361			      spx5_inst_rd(inst,
362					   DEV5G_PMAC_RX_JABBERS_CNT(tinst)));
363	sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
364			      spx5_inst_rd(inst, DEV5G_RX_SIZE64_CNT(tinst)));
365	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
366			      spx5_inst_rd(inst,
367					   DEV5G_PMAC_RX_SIZE64_CNT(tinst)));
368	sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
369			      spx5_inst_rd(inst,
370					   DEV5G_RX_SIZE65TO127_CNT(tinst)));
371	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
372			      spx5_inst_rd(inst,
373					   DEV5G_PMAC_RX_SIZE65TO127_CNT(tinst)));
374	sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
375			      spx5_inst_rd(inst,
376					   DEV5G_RX_SIZE128TO255_CNT(tinst)));
377	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
378			      spx5_inst_rd(inst,
379					   DEV5G_PMAC_RX_SIZE128TO255_CNT(tinst)));
380	sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
381			      spx5_inst_rd(inst,
382					   DEV5G_RX_SIZE256TO511_CNT(tinst)));
383	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
384			      spx5_inst_rd(inst,
385					   DEV5G_PMAC_RX_SIZE256TO511_CNT(tinst)));
386	sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
387			      spx5_inst_rd(inst,
388					   DEV5G_RX_SIZE512TO1023_CNT(tinst)));
389	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
390			      spx5_inst_rd(inst,
391					   DEV5G_PMAC_RX_SIZE512TO1023_CNT(tinst)));
392	sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
393			      spx5_inst_rd(inst,
394					   DEV5G_RX_SIZE1024TO1518_CNT(tinst)));
395	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
396			      spx5_inst_rd(inst,
397					   DEV5G_PMAC_RX_SIZE1024TO1518_CNT(tinst)));
398	sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
399			      spx5_inst_rd(inst,
400					   DEV5G_RX_SIZE1519TOMAX_CNT(tinst)));
401	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
402			      spx5_inst_rd(inst,
403					   DEV5G_PMAC_RX_SIZE1519TOMAX_CNT(tinst)));
404	sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
405			      spx5_inst_rd(inst, DEV5G_TX_SIZE64_CNT(tinst)));
406	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
407			      spx5_inst_rd(inst,
408					   DEV5G_PMAC_TX_SIZE64_CNT(tinst)));
409	sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
410			      spx5_inst_rd(inst,
411					   DEV5G_TX_SIZE65TO127_CNT(tinst)));
412	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
413			      spx5_inst_rd(inst,
414					   DEV5G_PMAC_TX_SIZE65TO127_CNT(tinst)));
415	sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
416			      spx5_inst_rd(inst,
417					   DEV5G_TX_SIZE128TO255_CNT(tinst)));
418	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
419			      spx5_inst_rd(inst,
420					   DEV5G_PMAC_TX_SIZE128TO255_CNT(tinst)));
421	sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
422			      spx5_inst_rd(inst,
423					   DEV5G_TX_SIZE256TO511_CNT(tinst)));
424	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
425			      spx5_inst_rd(inst,
426					   DEV5G_PMAC_TX_SIZE256TO511_CNT(tinst)));
427	sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
428			      spx5_inst_rd(inst,
429					   DEV5G_TX_SIZE512TO1023_CNT(tinst)));
430	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
431			      spx5_inst_rd(inst,
432					   DEV5G_PMAC_TX_SIZE512TO1023_CNT(tinst)));
433	sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
434			      spx5_inst_rd(inst,
435					   DEV5G_TX_SIZE1024TO1518_CNT(tinst)));
436	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
437			      spx5_inst_rd(inst,
438					   DEV5G_PMAC_TX_SIZE1024TO1518_CNT(tinst)));
439	sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
440			      spx5_inst_rd(inst,
441					   DEV5G_TX_SIZE1519TOMAX_CNT(tinst)));
442	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
443			      spx5_inst_rd(inst,
444					   DEV5G_PMAC_TX_SIZE1519TOMAX_CNT(tinst)));
445}
446
447static void sparx5_get_dev_misc_stats(u64 *portstats, void __iomem *inst, u32
448				      tinst)
449{
450	sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
451			      spx5_inst_rd(inst,
452					   DEV5G_MM_RX_ASSEMBLY_ERR_CNT(tinst)));
453	sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
454			      spx5_inst_rd(inst,
455					   DEV5G_MM_RX_ASSEMBLY_OK_CNT(tinst)));
456	sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
457			      spx5_inst_rd(inst,
458					   DEV5G_MM_RX_MERGE_FRAG_CNT(tinst)));
459	sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
460			      spx5_inst_rd(inst,
461					   DEV5G_MM_RX_SMD_ERR_CNT(tinst)));
462	sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
463			      spx5_inst_rd(inst,
464					   DEV5G_MM_TX_PFRAGMENT_CNT(tinst)));
465	sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
466			      spx5_inst_rd(inst,
467					   DEV5G_RX_BAD_BYTES_CNT(tinst)));
468	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
469			      spx5_inst_rd(inst,
470					   DEV5G_PMAC_RX_BAD_BYTES_CNT(tinst)));
471	sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
472			      spx5_inst_rd(inst, DEV5G_RX_IN_BYTES_CNT(tinst)));
473	sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
474			      spx5_inst_rd(inst,
475					   DEV5G_RX_IPG_SHRINK_CNT(tinst)));
476	sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
477			      spx5_inst_rd(inst,
478					   DEV5G_RX_TAGGED_FRMS_CNT(tinst)));
479	sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
480			      spx5_inst_rd(inst,
481					   DEV5G_RX_UNTAGGED_FRMS_CNT(tinst)));
482	sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
483			      spx5_inst_rd(inst,
484					   DEV5G_TX_OUT_BYTES_CNT(tinst)));
485	sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
486			      spx5_inst_rd(inst,
487					   DEV5G_TX_TAGGED_FRMS_CNT(tinst)));
488	sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
489			      spx5_inst_rd(inst,
490					   DEV5G_TX_UNTAGGED_FRMS_CNT(tinst)));
491	sparx5_update_counter(&portstats[spx5_stats_rx_hih_cksm_err_cnt],
492			      spx5_inst_rd(inst,
493					   DEV5G_RX_HIH_CKSM_ERR_CNT(tinst)));
494	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_hih_cksm_err_cnt],
495			      spx5_inst_rd(inst,
496					   DEV5G_PMAC_RX_HIH_CKSM_ERR_CNT(tinst)));
497	sparx5_update_counter(&portstats[spx5_stats_rx_xgmii_prot_err_cnt],
498			      spx5_inst_rd(inst,
499					   DEV5G_RX_XGMII_PROT_ERR_CNT(tinst)));
500	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_xgmii_prot_err_cnt],
501			      spx5_inst_rd(inst,
502					   DEV5G_PMAC_RX_XGMII_PROT_ERR_CNT(tinst)));
503}
504
505static void sparx5_get_device_stats(struct sparx5 *sparx5, int portno)
506{
507	u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
508	u32 tinst = sparx5_port_dev_index(portno);
509	u32 dev = sparx5_to_high_dev(portno);
510	void __iomem *inst;
511
512	inst = spx5_inst_get(sparx5, dev, tinst);
513	sparx5_get_dev_phy_stats(portstats, inst, tinst);
514	sparx5_get_dev_mac_stats(portstats, inst, tinst);
515	sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
516	sparx5_get_dev_rmon_stats(portstats, inst, tinst);
517	sparx5_get_dev_misc_stats(portstats, inst, tinst);
518}
519
520static void sparx5_get_asm_phy_stats(u64 *portstats, void __iomem *inst, int
521				     portno)
522{
523	sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
524			      spx5_inst_rd(inst,
525					   ASM_RX_SYMBOL_ERR_CNT(portno)));
526	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
527			      spx5_inst_rd(inst,
528					   ASM_PMAC_RX_SYMBOL_ERR_CNT(portno)));
529}
530
531static void sparx5_get_asm_mac_stats(u64 *portstats, void __iomem *inst, int
532				     portno)
533{
534	sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
535			      spx5_inst_rd(inst, ASM_TX_UC_CNT(portno)));
536	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
537			      spx5_inst_rd(inst, ASM_PMAC_TX_UC_CNT(portno)));
538	sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
539			      spx5_inst_rd(inst, ASM_TX_MC_CNT(portno)));
540	sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
541			      spx5_inst_rd(inst, ASM_TX_BC_CNT(portno)));
542	sparx5_update_counter(&portstats[spx5_stats_tx_backoff1_cnt],
543			      spx5_inst_rd(inst, ASM_TX_BACKOFF1_CNT(portno)));
544	sparx5_update_counter(&portstats[spx5_stats_tx_multi_coll_cnt],
545			      spx5_inst_rd(inst,
546					   ASM_TX_MULTI_COLL_CNT(portno)));
547	sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
548			      spx5_inst_rd(inst, ASM_RX_UC_CNT(portno)));
549	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
550			      spx5_inst_rd(inst, ASM_PMAC_RX_UC_CNT(portno)));
551	sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
552			      spx5_inst_rd(inst, ASM_RX_MC_CNT(portno)));
553	sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
554			      spx5_inst_rd(inst, ASM_RX_BC_CNT(portno)));
555	sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
556			      spx5_inst_rd(inst, ASM_RX_CRC_ERR_CNT(portno)));
557	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
558			      spx5_inst_rd(inst,
559					   ASM_PMAC_RX_CRC_ERR_CNT(portno)));
560	sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
561			      spx5_inst_rd(inst,
562					   ASM_RX_ALIGNMENT_LOST_CNT(portno)));
563	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
564			      spx5_inst_rd(inst,
565					   ASM_PMAC_RX_ALIGNMENT_LOST_CNT(portno)));
566	sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
567			      spx5_inst_rd(inst, ASM_TX_OK_BYTES_CNT(portno)));
568	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
569			      spx5_inst_rd(inst,
570					   ASM_PMAC_TX_OK_BYTES_CNT(portno)));
571	sparx5_update_counter(&portstats[spx5_stats_tx_defer_cnt],
572			      spx5_inst_rd(inst, ASM_TX_DEFER_CNT(portno)));
573	sparx5_update_counter(&portstats[spx5_stats_tx_late_coll_cnt],
574			      spx5_inst_rd(inst, ASM_TX_LATE_COLL_CNT(portno)));
575	sparx5_update_counter(&portstats[spx5_stats_tx_xcoll_cnt],
576			      spx5_inst_rd(inst, ASM_TX_XCOLL_CNT(portno)));
577	sparx5_update_counter(&portstats[spx5_stats_tx_csense_cnt],
578			      spx5_inst_rd(inst, ASM_TX_CSENSE_CNT(portno)));
579	sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
580			      spx5_inst_rd(inst, ASM_RX_OK_BYTES_CNT(portno)));
581	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
582			      spx5_inst_rd(inst,
583					   ASM_PMAC_RX_OK_BYTES_CNT(portno)));
584	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
585			      spx5_inst_rd(inst, ASM_PMAC_TX_MC_CNT(portno)));
586	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
587			      spx5_inst_rd(inst, ASM_PMAC_TX_BC_CNT(portno)));
588	sparx5_update_counter(&portstats[spx5_stats_tx_xdefer_cnt],
589			      spx5_inst_rd(inst, ASM_TX_XDEFER_CNT(portno)));
590	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
591			      spx5_inst_rd(inst, ASM_PMAC_RX_MC_CNT(portno)));
592	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
593			      spx5_inst_rd(inst, ASM_PMAC_RX_BC_CNT(portno)));
594	sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
595			      spx5_inst_rd(inst,
596					   ASM_RX_IN_RANGE_LEN_ERR_CNT(portno)));
597	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
598			      spx5_inst_rd(inst,
599					   ASM_PMAC_RX_IN_RANGE_LEN_ERR_CNT(portno)));
600	sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
601			      spx5_inst_rd(inst,
602					   ASM_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
603	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
604			      spx5_inst_rd(inst,
605					   ASM_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
606	sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
607			      spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
608	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
609			      spx5_inst_rd(inst,
610					   ASM_PMAC_RX_OVERSIZE_CNT(portno)));
611}
612
613static void sparx5_get_asm_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
614					  int portno)
615{
616	sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
617			      spx5_inst_rd(inst, ASM_TX_PAUSE_CNT(portno)));
618	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
619			      spx5_inst_rd(inst,
620					   ASM_PMAC_TX_PAUSE_CNT(portno)));
621	sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
622			      spx5_inst_rd(inst, ASM_RX_PAUSE_CNT(portno)));
623	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
624			      spx5_inst_rd(inst,
625					   ASM_PMAC_RX_PAUSE_CNT(portno)));
626	sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
627			      spx5_inst_rd(inst,
628					   ASM_RX_UNSUP_OPCODE_CNT(portno)));
629	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
630			      spx5_inst_rd(inst,
631					   ASM_PMAC_RX_UNSUP_OPCODE_CNT(portno)));
632}
633
634static void sparx5_get_asm_rmon_stats(u64 *portstats, void __iomem *inst, int
635				      portno)
636{
637	sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
638			      spx5_inst_rd(inst, ASM_RX_UNDERSIZE_CNT(portno)));
639	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
640			      spx5_inst_rd(inst,
641					   ASM_PMAC_RX_UNDERSIZE_CNT(portno)));
642	sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
643			      spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
644	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
645			      spx5_inst_rd(inst,
646					   ASM_PMAC_RX_OVERSIZE_CNT(portno)));
647	sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
648			      spx5_inst_rd(inst, ASM_RX_FRAGMENTS_CNT(portno)));
649	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
650			      spx5_inst_rd(inst,
651					   ASM_PMAC_RX_FRAGMENTS_CNT(portno)));
652	sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
653			      spx5_inst_rd(inst, ASM_RX_JABBERS_CNT(portno)));
654	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
655			      spx5_inst_rd(inst,
656					   ASM_PMAC_RX_JABBERS_CNT(portno)));
657	sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
658			      spx5_inst_rd(inst, ASM_RX_SIZE64_CNT(portno)));
659	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
660			      spx5_inst_rd(inst,
661					   ASM_PMAC_RX_SIZE64_CNT(portno)));
662	sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
663			      spx5_inst_rd(inst,
664					   ASM_RX_SIZE65TO127_CNT(portno)));
665	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
666			      spx5_inst_rd(inst,
667					   ASM_PMAC_RX_SIZE65TO127_CNT(portno)));
668	sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
669			      spx5_inst_rd(inst,
670					   ASM_RX_SIZE128TO255_CNT(portno)));
671	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
672			      spx5_inst_rd(inst,
673					   ASM_PMAC_RX_SIZE128TO255_CNT(portno)));
674	sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
675			      spx5_inst_rd(inst,
676					   ASM_RX_SIZE256TO511_CNT(portno)));
677	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
678			      spx5_inst_rd(inst,
679					   ASM_PMAC_RX_SIZE256TO511_CNT(portno)));
680	sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
681			      spx5_inst_rd(inst,
682					   ASM_RX_SIZE512TO1023_CNT(portno)));
683	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
684			      spx5_inst_rd(inst,
685					   ASM_PMAC_RX_SIZE512TO1023_CNT(portno)));
686	sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
687			      spx5_inst_rd(inst,
688					   ASM_RX_SIZE1024TO1518_CNT(portno)));
689	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
690			      spx5_inst_rd(inst,
691					   ASM_PMAC_RX_SIZE1024TO1518_CNT(portno)));
692	sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
693			      spx5_inst_rd(inst,
694					   ASM_RX_SIZE1519TOMAX_CNT(portno)));
695	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
696			      spx5_inst_rd(inst,
697					   ASM_PMAC_RX_SIZE1519TOMAX_CNT(portno)));
698	sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
699			      spx5_inst_rd(inst, ASM_TX_SIZE64_CNT(portno)));
700	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
701			      spx5_inst_rd(inst,
702					   ASM_PMAC_TX_SIZE64_CNT(portno)));
703	sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
704			      spx5_inst_rd(inst,
705					   ASM_TX_SIZE65TO127_CNT(portno)));
706	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
707			      spx5_inst_rd(inst,
708					   ASM_PMAC_TX_SIZE65TO127_CNT(portno)));
709	sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
710			      spx5_inst_rd(inst,
711					   ASM_TX_SIZE128TO255_CNT(portno)));
712	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
713			      spx5_inst_rd(inst,
714					   ASM_PMAC_TX_SIZE128TO255_CNT(portno)));
715	sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
716			      spx5_inst_rd(inst,
717					   ASM_TX_SIZE256TO511_CNT(portno)));
718	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
719			      spx5_inst_rd(inst,
720					   ASM_PMAC_TX_SIZE256TO511_CNT(portno)));
721	sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
722			      spx5_inst_rd(inst,
723					   ASM_TX_SIZE512TO1023_CNT(portno)));
724	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
725			      spx5_inst_rd(inst,
726					   ASM_PMAC_TX_SIZE512TO1023_CNT(portno)));
727	sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
728			      spx5_inst_rd(inst,
729					   ASM_TX_SIZE1024TO1518_CNT(portno)));
730	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
731			      spx5_inst_rd(inst,
732					   ASM_PMAC_TX_SIZE1024TO1518_CNT(portno)));
733	sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
734			      spx5_inst_rd(inst,
735					   ASM_TX_SIZE1519TOMAX_CNT(portno)));
736	sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
737			      spx5_inst_rd(inst,
738					   ASM_PMAC_TX_SIZE1519TOMAX_CNT(portno)));
739}
740
741static void sparx5_get_asm_misc_stats(u64 *portstats, void __iomem *inst, int
742				      portno)
743{
744	sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
745			      spx5_inst_rd(inst,
746					   ASM_MM_RX_ASSEMBLY_ERR_CNT(portno)));
747	sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
748			      spx5_inst_rd(inst,
749					   ASM_MM_RX_ASSEMBLY_OK_CNT(portno)));
750	sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
751			      spx5_inst_rd(inst,
752					   ASM_MM_RX_MERGE_FRAG_CNT(portno)));
753	sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
754			      spx5_inst_rd(inst,
755					   ASM_MM_RX_SMD_ERR_CNT(portno)));
756	sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
757			      spx5_inst_rd(inst,
758					   ASM_MM_TX_PFRAGMENT_CNT(portno)));
759	sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
760			      spx5_inst_rd(inst, ASM_RX_BAD_BYTES_CNT(portno)));
761	sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
762			      spx5_inst_rd(inst,
763					   ASM_PMAC_RX_BAD_BYTES_CNT(portno)));
764	sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
765			      spx5_inst_rd(inst, ASM_RX_IN_BYTES_CNT(portno)));
766	sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
767			      spx5_inst_rd(inst,
768					   ASM_RX_IPG_SHRINK_CNT(portno)));
769	sparx5_update_counter(&portstats[spx5_stats_rx_sync_lost_err_cnt],
770			      spx5_inst_rd(inst,
771					   ASM_RX_SYNC_LOST_ERR_CNT(portno)));
772	sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
773			      spx5_inst_rd(inst,
774					   ASM_RX_TAGGED_FRMS_CNT(portno)));
775	sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
776			      spx5_inst_rd(inst,
777					   ASM_RX_UNTAGGED_FRMS_CNT(portno)));
778	sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
779			      spx5_inst_rd(inst, ASM_TX_OUT_BYTES_CNT(portno)));
780	sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
781			      spx5_inst_rd(inst,
782					   ASM_TX_TAGGED_FRMS_CNT(portno)));
783	sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
784			      spx5_inst_rd(inst,
785					   ASM_TX_UNTAGGED_FRMS_CNT(portno)));
786}
787
788static void sparx5_get_asm_stats(struct sparx5 *sparx5, int portno)
789{
790	u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
791	void __iomem *inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
792
793	sparx5_get_asm_phy_stats(portstats, inst, portno);
794	sparx5_get_asm_mac_stats(portstats, inst, portno);
795	sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
796	sparx5_get_asm_rmon_stats(portstats, inst, portno);
797	sparx5_get_asm_misc_stats(portstats, inst, portno);
798}
799
800static const struct ethtool_rmon_hist_range sparx5_rmon_ranges[] = {
801	{    0,    64 },
802	{   65,   127 },
803	{  128,   255 },
804	{  256,   511 },
805	{  512,  1023 },
806	{ 1024,  1518 },
807	{ 1519, 10239 },
808	{}
809};
810
811static void sparx5_get_eth_phy_stats(struct net_device *ndev,
812				     struct ethtool_eth_phy_stats *phy_stats)
813{
814	struct sparx5_port *port = netdev_priv(ndev);
815	struct sparx5 *sparx5 = port->sparx5;
816	int portno = port->portno;
817	void __iomem *inst;
818	u64 *portstats;
819
820	portstats = &sparx5->stats[portno * sparx5->num_stats];
821	if (sparx5_is_baser(port->conf.portmode)) {
822		u32 tinst = sparx5_port_dev_index(portno);
823		u32 dev = sparx5_to_high_dev(portno);
824
825		inst = spx5_inst_get(sparx5, dev, tinst);
826		sparx5_get_dev_phy_stats(portstats, inst, tinst);
827	} else {
828		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
829		sparx5_get_asm_phy_stats(portstats, inst, portno);
830	}
831	phy_stats->SymbolErrorDuringCarrier =
832		portstats[spx5_stats_rx_symbol_err_cnt] +
833		portstats[spx5_stats_pmac_rx_symbol_err_cnt];
834}
835
836static void sparx5_get_eth_mac_stats(struct net_device *ndev,
837				     struct ethtool_eth_mac_stats *mac_stats)
838{
839	struct sparx5_port *port = netdev_priv(ndev);
840	struct sparx5 *sparx5 = port->sparx5;
841	int portno = port->portno;
842	void __iomem *inst;
843	u64 *portstats;
844
845	portstats = &sparx5->stats[portno * sparx5->num_stats];
846	if (sparx5_is_baser(port->conf.portmode)) {
847		u32 tinst = sparx5_port_dev_index(portno);
848		u32 dev = sparx5_to_high_dev(portno);
849
850		inst = spx5_inst_get(sparx5, dev, tinst);
851		sparx5_get_dev_mac_stats(portstats, inst, tinst);
852	} else {
853		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
854		sparx5_get_asm_mac_stats(portstats, inst, portno);
855	}
856	mac_stats->FramesTransmittedOK = portstats[spx5_stats_tx_uc_cnt] +
857		portstats[spx5_stats_pmac_tx_uc_cnt] +
858		portstats[spx5_stats_tx_mc_cnt] +
859		portstats[spx5_stats_tx_bc_cnt];
860	mac_stats->SingleCollisionFrames =
861		portstats[spx5_stats_tx_backoff1_cnt];
862	mac_stats->MultipleCollisionFrames =
863		portstats[spx5_stats_tx_multi_coll_cnt];
864	mac_stats->FramesReceivedOK = portstats[spx5_stats_rx_uc_cnt] +
865		portstats[spx5_stats_pmac_rx_uc_cnt] +
866		portstats[spx5_stats_rx_mc_cnt] +
867		portstats[spx5_stats_rx_bc_cnt];
868	mac_stats->FrameCheckSequenceErrors =
869		portstats[spx5_stats_rx_crc_err_cnt] +
870		portstats[spx5_stats_pmac_rx_crc_err_cnt];
871	mac_stats->AlignmentErrors = portstats[spx5_stats_rx_alignment_lost_cnt]
872		+ portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
873	mac_stats->OctetsTransmittedOK = portstats[spx5_stats_tx_ok_bytes_cnt] +
874		portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
875	mac_stats->FramesWithDeferredXmissions =
876		portstats[spx5_stats_tx_defer_cnt];
877	mac_stats->LateCollisions =
878		portstats[spx5_stats_tx_late_coll_cnt];
879	mac_stats->FramesAbortedDueToXSColls =
880		portstats[spx5_stats_tx_xcoll_cnt];
881	mac_stats->CarrierSenseErrors = portstats[spx5_stats_tx_csense_cnt];
882	mac_stats->OctetsReceivedOK = portstats[spx5_stats_rx_ok_bytes_cnt] +
883		portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
884	mac_stats->MulticastFramesXmittedOK = portstats[spx5_stats_tx_mc_cnt] +
885		portstats[spx5_stats_pmac_tx_mc_cnt];
886	mac_stats->BroadcastFramesXmittedOK = portstats[spx5_stats_tx_bc_cnt] +
887		portstats[spx5_stats_pmac_tx_bc_cnt];
888	mac_stats->FramesWithExcessiveDeferral =
889		portstats[spx5_stats_tx_xdefer_cnt];
890	mac_stats->MulticastFramesReceivedOK = portstats[spx5_stats_rx_mc_cnt] +
891		portstats[spx5_stats_pmac_rx_mc_cnt];
892	mac_stats->BroadcastFramesReceivedOK = portstats[spx5_stats_rx_bc_cnt] +
893		portstats[spx5_stats_pmac_rx_bc_cnt];
894	mac_stats->InRangeLengthErrors =
895		portstats[spx5_stats_rx_in_range_len_err_cnt] +
896		portstats[spx5_stats_pmac_rx_in_range_len_err_cnt];
897	mac_stats->OutOfRangeLengthField =
898		portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
899		portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt];
900	mac_stats->FrameTooLongErrors = portstats[spx5_stats_rx_oversize_cnt] +
901		portstats[spx5_stats_pmac_rx_oversize_cnt];
902}
903
904static void sparx5_get_eth_mac_ctrl_stats(struct net_device *ndev,
905					  struct ethtool_eth_ctrl_stats *mac_ctrl_stats)
906{
907	struct sparx5_port *port = netdev_priv(ndev);
908	struct sparx5 *sparx5 = port->sparx5;
909	int portno = port->portno;
910	void __iomem *inst;
911	u64 *portstats;
912
913	portstats = &sparx5->stats[portno * sparx5->num_stats];
914	if (sparx5_is_baser(port->conf.portmode)) {
915		u32 tinst = sparx5_port_dev_index(portno);
916		u32 dev = sparx5_to_high_dev(portno);
917
918		inst = spx5_inst_get(sparx5, dev, tinst);
919		sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
920	} else {
921		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
922		sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
923	}
924	mac_ctrl_stats->MACControlFramesTransmitted =
925		portstats[spx5_stats_tx_pause_cnt] +
926		portstats[spx5_stats_pmac_tx_pause_cnt];
927	mac_ctrl_stats->MACControlFramesReceived =
928		portstats[spx5_stats_rx_pause_cnt] +
929		portstats[spx5_stats_pmac_rx_pause_cnt];
930	mac_ctrl_stats->UnsupportedOpcodesReceived =
931		portstats[spx5_stats_rx_unsup_opcode_cnt] +
932		portstats[spx5_stats_pmac_rx_unsup_opcode_cnt];
933}
934
935static void sparx5_get_eth_rmon_stats(struct net_device *ndev,
936				      struct ethtool_rmon_stats *rmon_stats,
937				      const struct ethtool_rmon_hist_range **ranges)
938{
939	struct sparx5_port *port = netdev_priv(ndev);
940	struct sparx5 *sparx5 = port->sparx5;
941	int portno = port->portno;
942	void __iomem *inst;
943	u64 *portstats;
944
945	portstats = &sparx5->stats[portno * sparx5->num_stats];
946	if (sparx5_is_baser(port->conf.portmode)) {
947		u32 tinst = sparx5_port_dev_index(portno);
948		u32 dev = sparx5_to_high_dev(portno);
949
950		inst = spx5_inst_get(sparx5, dev, tinst);
951		sparx5_get_dev_rmon_stats(portstats, inst, tinst);
952	} else {
953		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
954		sparx5_get_asm_rmon_stats(portstats, inst, portno);
955	}
956	rmon_stats->undersize_pkts = portstats[spx5_stats_rx_undersize_cnt] +
957		portstats[spx5_stats_pmac_rx_undersize_cnt];
958	rmon_stats->oversize_pkts = portstats[spx5_stats_rx_oversize_cnt] +
959		portstats[spx5_stats_pmac_rx_oversize_cnt];
960	rmon_stats->fragments = portstats[spx5_stats_rx_fragments_cnt] +
961		portstats[spx5_stats_pmac_rx_fragments_cnt];
962	rmon_stats->jabbers = portstats[spx5_stats_rx_jabbers_cnt] +
963		portstats[spx5_stats_pmac_rx_jabbers_cnt];
964	rmon_stats->hist[0] = portstats[spx5_stats_rx_size64_cnt] +
965		portstats[spx5_stats_pmac_rx_size64_cnt];
966	rmon_stats->hist[1] = portstats[spx5_stats_rx_size65to127_cnt] +
967		portstats[spx5_stats_pmac_rx_size65to127_cnt];
968	rmon_stats->hist[2] = portstats[spx5_stats_rx_size128to255_cnt] +
969		portstats[spx5_stats_pmac_rx_size128to255_cnt];
970	rmon_stats->hist[3] = portstats[spx5_stats_rx_size256to511_cnt] +
971		portstats[spx5_stats_pmac_rx_size256to511_cnt];
972	rmon_stats->hist[4] = portstats[spx5_stats_rx_size512to1023_cnt] +
973		portstats[spx5_stats_pmac_rx_size512to1023_cnt];
974	rmon_stats->hist[5] = portstats[spx5_stats_rx_size1024to1518_cnt] +
975		portstats[spx5_stats_pmac_rx_size1024to1518_cnt];
976	rmon_stats->hist[6] = portstats[spx5_stats_rx_size1519tomax_cnt] +
977		portstats[spx5_stats_pmac_rx_size1519tomax_cnt];
978	rmon_stats->hist_tx[0] = portstats[spx5_stats_tx_size64_cnt] +
979		portstats[spx5_stats_pmac_tx_size64_cnt];
980	rmon_stats->hist_tx[1] = portstats[spx5_stats_tx_size65to127_cnt] +
981		portstats[spx5_stats_pmac_tx_size65to127_cnt];
982	rmon_stats->hist_tx[2] = portstats[spx5_stats_tx_size128to255_cnt] +
983		portstats[spx5_stats_pmac_tx_size128to255_cnt];
984	rmon_stats->hist_tx[3] = portstats[spx5_stats_tx_size256to511_cnt] +
985		portstats[spx5_stats_pmac_tx_size256to511_cnt];
986	rmon_stats->hist_tx[4] = portstats[spx5_stats_tx_size512to1023_cnt] +
987		portstats[spx5_stats_pmac_tx_size512to1023_cnt];
988	rmon_stats->hist_tx[5] = portstats[spx5_stats_tx_size1024to1518_cnt] +
989		portstats[spx5_stats_pmac_tx_size1024to1518_cnt];
990	rmon_stats->hist_tx[6] = portstats[spx5_stats_tx_size1519tomax_cnt] +
991		portstats[spx5_stats_pmac_tx_size1519tomax_cnt];
992	*ranges = sparx5_rmon_ranges;
993}
994
995static int sparx5_get_sset_count(struct net_device *ndev, int sset)
996{
997	struct sparx5_port *port = netdev_priv(ndev);
998	struct sparx5  *sparx5 = port->sparx5;
999
1000	if (sset != ETH_SS_STATS)
1001		return -EOPNOTSUPP;
1002	return sparx5->num_ethtool_stats;
1003}
1004
1005static void sparx5_get_sset_strings(struct net_device *ndev, u32 sset, u8 *data)
1006{
1007	struct sparx5_port *port = netdev_priv(ndev);
1008	struct sparx5  *sparx5 = port->sparx5;
1009	int idx;
1010
1011	if (sset != ETH_SS_STATS)
1012		return;
1013
1014	for (idx = 0; idx < sparx5->num_ethtool_stats; idx++)
1015		ethtool_puts(&data, sparx5->stats_layout[idx]);
1016}
1017
1018static void sparx5_get_sset_data(struct net_device *ndev,
1019				 struct ethtool_stats *stats, u64 *data)
1020{
1021	struct sparx5_port *port = netdev_priv(ndev);
1022	struct sparx5 *sparx5 = port->sparx5;
1023	int portno = port->portno;
1024	void __iomem *inst;
1025	u64 *portstats;
1026	int idx;
1027
1028	portstats = &sparx5->stats[portno * sparx5->num_stats];
1029	if (sparx5_is_baser(port->conf.portmode)) {
1030		u32 tinst = sparx5_port_dev_index(portno);
1031		u32 dev = sparx5_to_high_dev(portno);
1032
1033		inst = spx5_inst_get(sparx5, dev, tinst);
1034		sparx5_get_dev_misc_stats(portstats, inst, tinst);
1035	} else {
1036		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
1037		sparx5_get_asm_misc_stats(portstats, inst, portno);
1038	}
1039	sparx5_get_ana_ac_stats_stats(sparx5, portno);
1040	sparx5_get_queue_sys_stats(sparx5, portno);
1041	/* Copy port counters to the ethtool buffer */
1042	for (idx = spx5_stats_mm_rx_assembly_err_cnt;
1043	     idx < spx5_stats_mm_rx_assembly_err_cnt +
1044	     sparx5->num_ethtool_stats; idx++)
1045		*data++ = portstats[idx];
1046}
1047
1048void sparx5_get_stats64(struct net_device *ndev,
1049			struct rtnl_link_stats64 *stats)
1050{
1051	struct sparx5_port *port = netdev_priv(ndev);
1052	struct sparx5 *sparx5 = port->sparx5;
1053	u64 *portstats;
1054	int idx;
1055
1056	if (!sparx5->stats)
1057		return; /* Not initialized yet */
1058
1059	portstats = &sparx5->stats[port->portno * sparx5->num_stats];
1060
1061	stats->rx_packets = portstats[spx5_stats_rx_uc_cnt] +
1062		portstats[spx5_stats_pmac_rx_uc_cnt] +
1063		portstats[spx5_stats_rx_mc_cnt] +
1064		portstats[spx5_stats_rx_bc_cnt];
1065	stats->tx_packets = portstats[spx5_stats_tx_uc_cnt] +
1066		portstats[spx5_stats_pmac_tx_uc_cnt] +
1067		portstats[spx5_stats_tx_mc_cnt] +
1068		portstats[spx5_stats_tx_bc_cnt];
1069	stats->rx_bytes = portstats[spx5_stats_rx_ok_bytes_cnt] +
1070		portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
1071	stats->tx_bytes = portstats[spx5_stats_tx_ok_bytes_cnt] +
1072		portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
1073	stats->rx_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1074		portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1075		portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1076		portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1077		portstats[spx5_stats_rx_oversize_cnt] +
1078		portstats[spx5_stats_pmac_rx_oversize_cnt] +
1079		portstats[spx5_stats_rx_crc_err_cnt] +
1080		portstats[spx5_stats_pmac_rx_crc_err_cnt] +
1081		portstats[spx5_stats_rx_alignment_lost_cnt] +
1082		portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1083	stats->tx_errors = portstats[spx5_stats_tx_xcoll_cnt] +
1084		portstats[spx5_stats_tx_csense_cnt] +
1085		portstats[spx5_stats_tx_late_coll_cnt];
1086	stats->multicast = portstats[spx5_stats_rx_mc_cnt] +
1087		portstats[spx5_stats_pmac_rx_mc_cnt];
1088	stats->collisions = portstats[spx5_stats_tx_late_coll_cnt] +
1089		portstats[spx5_stats_tx_xcoll_cnt] +
1090		portstats[spx5_stats_tx_backoff1_cnt];
1091	stats->rx_length_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1092		portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1093		portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1094		portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1095		portstats[spx5_stats_rx_oversize_cnt] +
1096		portstats[spx5_stats_pmac_rx_oversize_cnt];
1097	stats->rx_crc_errors = portstats[spx5_stats_rx_crc_err_cnt] +
1098		portstats[spx5_stats_pmac_rx_crc_err_cnt];
1099	stats->rx_frame_errors = portstats[spx5_stats_rx_alignment_lost_cnt] +
1100		portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1101	stats->tx_aborted_errors = portstats[spx5_stats_tx_xcoll_cnt];
1102	stats->tx_carrier_errors = portstats[spx5_stats_tx_csense_cnt];
1103	stats->tx_window_errors = portstats[spx5_stats_tx_late_coll_cnt];
1104	stats->rx_dropped = portstats[spx5_stats_ana_ac_port_stat_lsb_cnt];
1105	for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx)
1106		stats->rx_dropped += portstats[spx5_stats_green_p0_rx_port_drop
1107					       + idx];
1108	stats->tx_dropped = portstats[spx5_stats_tx_local_drop];
1109}
1110
1111static void sparx5_update_port_stats(struct sparx5 *sparx5, int portno)
1112{
1113	if (sparx5_is_baser(sparx5->ports[portno]->conf.portmode))
1114		sparx5_get_device_stats(sparx5, portno);
1115	else
1116		sparx5_get_asm_stats(sparx5, portno);
1117	sparx5_get_ana_ac_stats_stats(sparx5, portno);
1118	sparx5_get_queue_sys_stats(sparx5, portno);
1119}
1120
1121static void sparx5_update_stats(struct sparx5 *sparx5)
1122{
1123	int idx;
1124
1125	for (idx = 0; idx < SPX5_PORTS; idx++)
1126		if (sparx5->ports[idx])
1127			sparx5_update_port_stats(sparx5, idx);
1128}
1129
1130static void sparx5_check_stats_work(struct work_struct *work)
1131{
1132	struct delayed_work *dwork = to_delayed_work(work);
1133	struct sparx5 *sparx5 = container_of(dwork,
1134					     struct sparx5,
1135					     stats_work);
1136
1137	sparx5_update_stats(sparx5);
1138
1139	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1140			   SPX5_STATS_CHECK_DELAY);
1141}
1142
1143static int sparx5_get_link_settings(struct net_device *ndev,
1144				    struct ethtool_link_ksettings *cmd)
1145{
1146	struct sparx5_port *port = netdev_priv(ndev);
1147
1148	return phylink_ethtool_ksettings_get(port->phylink, cmd);
1149}
1150
1151static int sparx5_set_link_settings(struct net_device *ndev,
1152				    const struct ethtool_link_ksettings *cmd)
1153{
1154	struct sparx5_port *port = netdev_priv(ndev);
1155
1156	return phylink_ethtool_ksettings_set(port->phylink, cmd);
1157}
1158
1159static void sparx5_config_stats(struct sparx5 *sparx5)
1160{
1161	/* Enable global events for port policer drops */
1162	spx5_rmw(ANA_AC_PORT_SGE_CFG_MASK_SET(0xf0f0),
1163		 ANA_AC_PORT_SGE_CFG_MASK,
1164		 sparx5,
1165		 ANA_AC_PORT_SGE_CFG(SPX5_PORT_POLICER_DROPS));
1166}
1167
1168static void sparx5_config_port_stats(struct sparx5 *sparx5, int portno)
1169{
1170	/* Clear Queue System counters */
1171	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno) |
1172		XQS_STAT_CFG_STAT_CLEAR_SHOT_SET(3), sparx5,
1173		XQS_STAT_CFG);
1174
1175	/* Use counter for port policer drop count */
1176	spx5_rmw(ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE_SET(1) |
1177		 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE_SET(0) |
1178		 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK_SET(0xff),
1179		 ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE |
1180		 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE |
1181		 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK,
1182		 sparx5, ANA_AC_PORT_STAT_CFG(portno, SPX5_PORT_POLICER_DROPS));
1183}
1184
1185static int sparx5_get_ts_info(struct net_device *dev,
1186			      struct ethtool_ts_info *info)
1187{
1188	struct sparx5_port *port = netdev_priv(dev);
1189	struct sparx5 *sparx5 = port->sparx5;
1190	struct sparx5_phc *phc;
1191
1192	if (!sparx5->ptp)
1193		return ethtool_op_get_ts_info(dev, info);
1194
1195	phc = &sparx5->phc[SPARX5_PHC_PORT];
1196
1197	info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
1198	if (info->phc_index == -1) {
1199		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1200					 SOF_TIMESTAMPING_RX_SOFTWARE |
1201					 SOF_TIMESTAMPING_SOFTWARE;
1202		return 0;
1203	}
1204	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1205				 SOF_TIMESTAMPING_RX_SOFTWARE |
1206				 SOF_TIMESTAMPING_SOFTWARE |
1207				 SOF_TIMESTAMPING_TX_HARDWARE |
1208				 SOF_TIMESTAMPING_RX_HARDWARE |
1209				 SOF_TIMESTAMPING_RAW_HARDWARE;
1210	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
1211			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
1212	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1213			   BIT(HWTSTAMP_FILTER_ALL);
1214
1215	return 0;
1216}
1217
1218const struct ethtool_ops sparx5_ethtool_ops = {
1219	.get_sset_count         = sparx5_get_sset_count,
1220	.get_strings            = sparx5_get_sset_strings,
1221	.get_ethtool_stats      = sparx5_get_sset_data,
1222	.get_link_ksettings	= sparx5_get_link_settings,
1223	.set_link_ksettings	= sparx5_set_link_settings,
1224	.get_link               = ethtool_op_get_link,
1225	.get_eth_phy_stats      = sparx5_get_eth_phy_stats,
1226	.get_eth_mac_stats      = sparx5_get_eth_mac_stats,
1227	.get_eth_ctrl_stats     = sparx5_get_eth_mac_ctrl_stats,
1228	.get_rmon_stats         = sparx5_get_eth_rmon_stats,
1229	.get_ts_info            = sparx5_get_ts_info,
1230};
1231
1232int sparx_stats_init(struct sparx5 *sparx5)
1233{
1234	char queue_name[32];
1235	int portno;
1236
1237	sparx5->stats_layout = sparx5_stats_layout;
1238	sparx5->num_stats = spx5_stats_count;
1239	sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
1240	sparx5->stats = devm_kcalloc(sparx5->dev,
1241				     SPX5_PORTS_ALL * sparx5->num_stats,
1242				     sizeof(u64), GFP_KERNEL);
1243	if (!sparx5->stats)
1244		return -ENOMEM;
1245
1246	mutex_init(&sparx5->queue_stats_lock);
1247	sparx5_config_stats(sparx5);
1248	for (portno = 0; portno < SPX5_PORTS; portno++)
1249		if (sparx5->ports[portno])
1250			sparx5_config_port_stats(sparx5, portno);
1251
1252	snprintf(queue_name, sizeof(queue_name), "%s-stats",
1253		 dev_name(sparx5->dev));
1254	sparx5->stats_queue = create_singlethread_workqueue(queue_name);
1255	if (!sparx5->stats_queue)
1256		return -ENOMEM;
1257
1258	INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
1259	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1260			   SPX5_STATS_CHECK_DELAY);
1261
1262	return 0;
1263}
1264