clk: uniphier: Fix fixed-rate initialization
[linux-2.6-microblaze.git] / drivers / net / ethernet / microchip / sparx5 / sparx5_ethtool.c
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 */
17 static 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
24 enum 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
128 static 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
201 static 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
230 static 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
239 static 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
250 static 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
317 static 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
338 static 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
447 static 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
505 static 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
520 static 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
531 static 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
613 static 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
634 static 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
741 static 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
788 static 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
800 static 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
811 static 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
836 static 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
904 static 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
935 static 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
995 static 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
1005 static 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                 strncpy(data + idx * ETH_GSTRING_LEN,
1016                         sparx5->stats_layout[idx], ETH_GSTRING_LEN);
1017 }
1018
1019 static void sparx5_get_sset_data(struct net_device *ndev,
1020                                  struct ethtool_stats *stats, u64 *data)
1021 {
1022         struct sparx5_port *port = netdev_priv(ndev);
1023         struct sparx5 *sparx5 = port->sparx5;
1024         int portno = port->portno;
1025         void __iomem *inst;
1026         u64 *portstats;
1027         int idx;
1028
1029         portstats = &sparx5->stats[portno * sparx5->num_stats];
1030         if (sparx5_is_baser(port->conf.portmode)) {
1031                 u32 tinst = sparx5_port_dev_index(portno);
1032                 u32 dev = sparx5_to_high_dev(portno);
1033
1034                 inst = spx5_inst_get(sparx5, dev, tinst);
1035                 sparx5_get_dev_misc_stats(portstats, inst, tinst);
1036         } else {
1037                 inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
1038                 sparx5_get_asm_misc_stats(portstats, inst, portno);
1039         }
1040         sparx5_get_ana_ac_stats_stats(sparx5, portno);
1041         sparx5_get_queue_sys_stats(sparx5, portno);
1042         /* Copy port counters to the ethtool buffer */
1043         for (idx = spx5_stats_mm_rx_assembly_err_cnt;
1044              idx < spx5_stats_mm_rx_assembly_err_cnt +
1045              sparx5->num_ethtool_stats; idx++)
1046                 *data++ = portstats[idx];
1047 }
1048
1049 void sparx5_get_stats64(struct net_device *ndev,
1050                         struct rtnl_link_stats64 *stats)
1051 {
1052         struct sparx5_port *port = netdev_priv(ndev);
1053         struct sparx5 *sparx5 = port->sparx5;
1054         u64 *portstats;
1055         int idx;
1056
1057         if (!sparx5->stats)
1058                 return; /* Not initialized yet */
1059
1060         portstats = &sparx5->stats[port->portno * sparx5->num_stats];
1061
1062         stats->rx_packets = portstats[spx5_stats_rx_uc_cnt] +
1063                 portstats[spx5_stats_pmac_rx_uc_cnt] +
1064                 portstats[spx5_stats_rx_mc_cnt] +
1065                 portstats[spx5_stats_rx_bc_cnt];
1066         stats->tx_packets = portstats[spx5_stats_tx_uc_cnt] +
1067                 portstats[spx5_stats_pmac_tx_uc_cnt] +
1068                 portstats[spx5_stats_tx_mc_cnt] +
1069                 portstats[spx5_stats_tx_bc_cnt];
1070         stats->rx_bytes = portstats[spx5_stats_rx_ok_bytes_cnt] +
1071                 portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
1072         stats->tx_bytes = portstats[spx5_stats_tx_ok_bytes_cnt] +
1073                 portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
1074         stats->rx_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1075                 portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1076                 portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1077                 portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1078                 portstats[spx5_stats_rx_oversize_cnt] +
1079                 portstats[spx5_stats_pmac_rx_oversize_cnt] +
1080                 portstats[spx5_stats_rx_crc_err_cnt] +
1081                 portstats[spx5_stats_pmac_rx_crc_err_cnt] +
1082                 portstats[spx5_stats_rx_alignment_lost_cnt] +
1083                 portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1084         stats->tx_errors = portstats[spx5_stats_tx_xcoll_cnt] +
1085                 portstats[spx5_stats_tx_csense_cnt] +
1086                 portstats[spx5_stats_tx_late_coll_cnt];
1087         stats->multicast = portstats[spx5_stats_rx_mc_cnt] +
1088                 portstats[spx5_stats_pmac_rx_mc_cnt];
1089         stats->collisions = portstats[spx5_stats_tx_late_coll_cnt] +
1090                 portstats[spx5_stats_tx_xcoll_cnt] +
1091                 portstats[spx5_stats_tx_backoff1_cnt];
1092         stats->rx_length_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1093                 portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1094                 portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1095                 portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1096                 portstats[spx5_stats_rx_oversize_cnt] +
1097                 portstats[spx5_stats_pmac_rx_oversize_cnt];
1098         stats->rx_crc_errors = portstats[spx5_stats_rx_crc_err_cnt] +
1099                 portstats[spx5_stats_pmac_rx_crc_err_cnt];
1100         stats->rx_frame_errors = portstats[spx5_stats_rx_alignment_lost_cnt] +
1101                 portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1102         stats->tx_aborted_errors = portstats[spx5_stats_tx_xcoll_cnt];
1103         stats->tx_carrier_errors = portstats[spx5_stats_tx_csense_cnt];
1104         stats->tx_window_errors = portstats[spx5_stats_tx_late_coll_cnt];
1105         stats->rx_dropped = portstats[spx5_stats_ana_ac_port_stat_lsb_cnt];
1106         for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++stats)
1107                 stats->rx_dropped += portstats[spx5_stats_green_p0_rx_port_drop
1108                                                + idx];
1109         stats->tx_dropped = portstats[spx5_stats_tx_local_drop];
1110 }
1111
1112 static void sparx5_update_port_stats(struct sparx5 *sparx5, int portno)
1113 {
1114         if (sparx5_is_baser(sparx5->ports[portno]->conf.portmode))
1115                 sparx5_get_device_stats(sparx5, portno);
1116         else
1117                 sparx5_get_asm_stats(sparx5, portno);
1118         sparx5_get_ana_ac_stats_stats(sparx5, portno);
1119         sparx5_get_queue_sys_stats(sparx5, portno);
1120 }
1121
1122 static void sparx5_update_stats(struct sparx5 *sparx5)
1123 {
1124         int idx;
1125
1126         for (idx = 0; idx < SPX5_PORTS; idx++)
1127                 if (sparx5->ports[idx])
1128                         sparx5_update_port_stats(sparx5, idx);
1129 }
1130
1131 static void sparx5_check_stats_work(struct work_struct *work)
1132 {
1133         struct delayed_work *dwork = to_delayed_work(work);
1134         struct sparx5 *sparx5 = container_of(dwork,
1135                                              struct sparx5,
1136                                              stats_work);
1137
1138         sparx5_update_stats(sparx5);
1139
1140         queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1141                            SPX5_STATS_CHECK_DELAY);
1142 }
1143
1144 static int sparx5_get_link_settings(struct net_device *ndev,
1145                                     struct ethtool_link_ksettings *cmd)
1146 {
1147         struct sparx5_port *port = netdev_priv(ndev);
1148
1149         return phylink_ethtool_ksettings_get(port->phylink, cmd);
1150 }
1151
1152 static int sparx5_set_link_settings(struct net_device *ndev,
1153                                     const struct ethtool_link_ksettings *cmd)
1154 {
1155         struct sparx5_port *port = netdev_priv(ndev);
1156
1157         return phylink_ethtool_ksettings_set(port->phylink, cmd);
1158 }
1159
1160 static void sparx5_config_stats(struct sparx5 *sparx5)
1161 {
1162         /* Enable global events for port policer drops */
1163         spx5_rmw(ANA_AC_PORT_SGE_CFG_MASK_SET(0xf0f0),
1164                  ANA_AC_PORT_SGE_CFG_MASK,
1165                  sparx5,
1166                  ANA_AC_PORT_SGE_CFG(SPX5_PORT_POLICER_DROPS));
1167 }
1168
1169 static void sparx5_config_port_stats(struct sparx5 *sparx5, int portno)
1170 {
1171         /* Clear Queue System counters */
1172         spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno) |
1173                 XQS_STAT_CFG_STAT_CLEAR_SHOT_SET(3), sparx5,
1174                 XQS_STAT_CFG);
1175
1176         /* Use counter for port policer drop count */
1177         spx5_rmw(ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE_SET(1) |
1178                  ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE_SET(0) |
1179                  ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK_SET(0xff),
1180                  ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE |
1181                  ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE |
1182                  ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK,
1183                  sparx5, ANA_AC_PORT_STAT_CFG(portno, SPX5_PORT_POLICER_DROPS));
1184 }
1185
1186 const struct ethtool_ops sparx5_ethtool_ops = {
1187         .get_sset_count         = sparx5_get_sset_count,
1188         .get_strings            = sparx5_get_sset_strings,
1189         .get_ethtool_stats      = sparx5_get_sset_data,
1190         .get_link_ksettings     = sparx5_get_link_settings,
1191         .set_link_ksettings     = sparx5_set_link_settings,
1192         .get_link               = ethtool_op_get_link,
1193         .get_eth_phy_stats      = sparx5_get_eth_phy_stats,
1194         .get_eth_mac_stats      = sparx5_get_eth_mac_stats,
1195         .get_eth_ctrl_stats     = sparx5_get_eth_mac_ctrl_stats,
1196         .get_rmon_stats         = sparx5_get_eth_rmon_stats,
1197 };
1198
1199 int sparx_stats_init(struct sparx5 *sparx5)
1200 {
1201         char queue_name[32];
1202         int portno;
1203
1204         sparx5->stats_layout = sparx5_stats_layout;
1205         sparx5->num_stats = spx5_stats_count;
1206         sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
1207         sparx5->stats = devm_kcalloc(sparx5->dev,
1208                                      SPX5_PORTS_ALL * sparx5->num_stats,
1209                                      sizeof(u64), GFP_KERNEL);
1210         if (!sparx5->stats)
1211                 return -ENOMEM;
1212
1213         mutex_init(&sparx5->queue_stats_lock);
1214         sparx5_config_stats(sparx5);
1215         for (portno = 0; portno < SPX5_PORTS; portno++)
1216                 if (sparx5->ports[portno])
1217                         sparx5_config_port_stats(sparx5, portno);
1218
1219         snprintf(queue_name, sizeof(queue_name), "%s-stats",
1220                  dev_name(sparx5->dev));
1221         sparx5->stats_queue = create_singlethread_workqueue(queue_name);
1222         INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
1223         queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1224                            SPX5_STATS_CHECK_DELAY);
1225
1226         return 0;
1227 }