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(cnt: stats, val: 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(cnt: stats, val: 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(cnt: stats, val: spx5_rd(sparx5, XQS_CNT(addr)));
223 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_local_drop],
224 val: spx5_rd(sparx5, XQS_CNT(32)));
225 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_local_drop],
226 val: spx5_rd(sparx5, XQS_CNT(272)));
227 mutex_unlock(lock: &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(cnt: &portstats[spx5_stats_ana_ac_port_stat_lsb_cnt],
235 val: 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(cnt: &portstats[spx5_stats_rx_symbol_err_cnt],
243 val: spx5_inst_rd(iomem: inst,
244 DEV5G_RX_SYMBOL_ERR_CNT(tinst)));
245 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_symbol_err_cnt],
246 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_tx_uc_cnt],
254 val: spx5_inst_rd(iomem: inst, DEV5G_TX_UC_CNT(tinst)));
255 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_uc_cnt],
256 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_TX_UC_CNT(tinst)));
257 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_mc_cnt],
258 val: spx5_inst_rd(iomem: inst, DEV5G_TX_MC_CNT(tinst)));
259 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_bc_cnt],
260 val: spx5_inst_rd(iomem: inst, DEV5G_TX_BC_CNT(tinst)));
261 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_uc_cnt],
262 val: spx5_inst_rd(iomem: inst, DEV5G_RX_UC_CNT(tinst)));
263 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_uc_cnt],
264 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_RX_UC_CNT(tinst)));
265 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_mc_cnt],
266 val: spx5_inst_rd(iomem: inst, DEV5G_RX_MC_CNT(tinst)));
267 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_bc_cnt],
268 val: spx5_inst_rd(iomem: inst, DEV5G_RX_BC_CNT(tinst)));
269 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_crc_err_cnt],
270 val: spx5_inst_rd(iomem: inst, DEV5G_RX_CRC_ERR_CNT(tinst)));
271 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_crc_err_cnt],
272 val: spx5_inst_rd(iomem: inst,
273 DEV5G_PMAC_RX_CRC_ERR_CNT(tinst)));
274 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_alignment_lost_cnt],
275 val: spx5_inst_rd(iomem: inst,
276 DEV5G_RX_ALIGNMENT_LOST_CNT(tinst)));
277 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
278 val: spx5_inst_rd(iomem: inst,
279 DEV5G_PMAC_RX_ALIGNMENT_LOST_CNT(tinst)));
280 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_ok_bytes_cnt],
281 val: spx5_inst_rd(iomem: inst, DEV5G_TX_OK_BYTES_CNT(tinst)));
282 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
283 val: spx5_inst_rd(iomem: inst,
284 DEV5G_PMAC_TX_OK_BYTES_CNT(tinst)));
285 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_ok_bytes_cnt],
286 val: spx5_inst_rd(iomem: inst, DEV5G_RX_OK_BYTES_CNT(tinst)));
287 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
288 val: spx5_inst_rd(iomem: inst,
289 DEV5G_PMAC_RX_OK_BYTES_CNT(tinst)));
290 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_mc_cnt],
291 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_TX_MC_CNT(tinst)));
292 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_bc_cnt],
293 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_TX_BC_CNT(tinst)));
294 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_mc_cnt],
295 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_RX_MC_CNT(tinst)));
296 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_bc_cnt],
297 val: spx5_inst_rd(iomem: inst, DEV5G_PMAC_RX_BC_CNT(tinst)));
298 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_in_range_len_err_cnt],
299 val: spx5_inst_rd(iomem: inst,
300 DEV5G_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
301 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
302 val: spx5_inst_rd(iomem: inst,
303 DEV5G_PMAC_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
304 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_out_of_range_len_err_cnt],
305 val: spx5_inst_rd(iomem: inst,
306 DEV5G_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
307 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
308 val: spx5_inst_rd(iomem: inst,
309 DEV5G_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
310 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_oversize_cnt],
311 val: spx5_inst_rd(iomem: inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
312 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_oversize_cnt],
313 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_tx_pause_cnt],
321 val: spx5_inst_rd(iomem: inst, DEV5G_TX_PAUSE_CNT(tinst)));
322 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_pause_cnt],
323 val: spx5_inst_rd(iomem: inst,
324 DEV5G_PMAC_TX_PAUSE_CNT(tinst)));
325 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_pause_cnt],
326 val: spx5_inst_rd(iomem: inst, DEV5G_RX_PAUSE_CNT(tinst)));
327 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_pause_cnt],
328 val: spx5_inst_rd(iomem: inst,
329 DEV5G_PMAC_RX_PAUSE_CNT(tinst)));
330 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_unsup_opcode_cnt],
331 val: spx5_inst_rd(iomem: inst,
332 DEV5G_RX_UNSUP_OPCODE_CNT(tinst)));
333 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
334 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_rx_undersize_cnt],
342 val: spx5_inst_rd(iomem: inst,
343 DEV5G_RX_UNDERSIZE_CNT(tinst)));
344 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_undersize_cnt],
345 val: spx5_inst_rd(iomem: inst,
346 DEV5G_PMAC_RX_UNDERSIZE_CNT(tinst)));
347 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_oversize_cnt],
348 val: spx5_inst_rd(iomem: inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
349 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_oversize_cnt],
350 val: spx5_inst_rd(iomem: inst,
351 DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
352 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_fragments_cnt],
353 val: spx5_inst_rd(iomem: inst,
354 DEV5G_RX_FRAGMENTS_CNT(tinst)));
355 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_fragments_cnt],
356 val: spx5_inst_rd(iomem: inst,
357 DEV5G_PMAC_RX_FRAGMENTS_CNT(tinst)));
358 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_jabbers_cnt],
359 val: spx5_inst_rd(iomem: inst, DEV5G_RX_JABBERS_CNT(tinst)));
360 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_jabbers_cnt],
361 val: spx5_inst_rd(iomem: inst,
362 DEV5G_PMAC_RX_JABBERS_CNT(tinst)));
363 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size64_cnt],
364 val: spx5_inst_rd(iomem: inst, DEV5G_RX_SIZE64_CNT(tinst)));
365 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size64_cnt],
366 val: spx5_inst_rd(iomem: inst,
367 DEV5G_PMAC_RX_SIZE64_CNT(tinst)));
368 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size65to127_cnt],
369 val: spx5_inst_rd(iomem: inst,
370 DEV5G_RX_SIZE65TO127_CNT(tinst)));
371 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size65to127_cnt],
372 val: spx5_inst_rd(iomem: inst,
373 DEV5G_PMAC_RX_SIZE65TO127_CNT(tinst)));
374 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size128to255_cnt],
375 val: spx5_inst_rd(iomem: inst,
376 DEV5G_RX_SIZE128TO255_CNT(tinst)));
377 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size128to255_cnt],
378 val: spx5_inst_rd(iomem: inst,
379 DEV5G_PMAC_RX_SIZE128TO255_CNT(tinst)));
380 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size256to511_cnt],
381 val: spx5_inst_rd(iomem: inst,
382 DEV5G_RX_SIZE256TO511_CNT(tinst)));
383 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size256to511_cnt],
384 val: spx5_inst_rd(iomem: inst,
385 DEV5G_PMAC_RX_SIZE256TO511_CNT(tinst)));
386 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size512to1023_cnt],
387 val: spx5_inst_rd(iomem: inst,
388 DEV5G_RX_SIZE512TO1023_CNT(tinst)));
389 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size512to1023_cnt],
390 val: spx5_inst_rd(iomem: inst,
391 DEV5G_PMAC_RX_SIZE512TO1023_CNT(tinst)));
392 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size1024to1518_cnt],
393 val: spx5_inst_rd(iomem: inst,
394 DEV5G_RX_SIZE1024TO1518_CNT(tinst)));
395 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
396 val: spx5_inst_rd(iomem: inst,
397 DEV5G_PMAC_RX_SIZE1024TO1518_CNT(tinst)));
398 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size1519tomax_cnt],
399 val: spx5_inst_rd(iomem: inst,
400 DEV5G_RX_SIZE1519TOMAX_CNT(tinst)));
401 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
402 val: spx5_inst_rd(iomem: inst,
403 DEV5G_PMAC_RX_SIZE1519TOMAX_CNT(tinst)));
404 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size64_cnt],
405 val: spx5_inst_rd(iomem: inst, DEV5G_TX_SIZE64_CNT(tinst)));
406 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size64_cnt],
407 val: spx5_inst_rd(iomem: inst,
408 DEV5G_PMAC_TX_SIZE64_CNT(tinst)));
409 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size65to127_cnt],
410 val: spx5_inst_rd(iomem: inst,
411 DEV5G_TX_SIZE65TO127_CNT(tinst)));
412 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size65to127_cnt],
413 val: spx5_inst_rd(iomem: inst,
414 DEV5G_PMAC_TX_SIZE65TO127_CNT(tinst)));
415 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size128to255_cnt],
416 val: spx5_inst_rd(iomem: inst,
417 DEV5G_TX_SIZE128TO255_CNT(tinst)));
418 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size128to255_cnt],
419 val: spx5_inst_rd(iomem: inst,
420 DEV5G_PMAC_TX_SIZE128TO255_CNT(tinst)));
421 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size256to511_cnt],
422 val: spx5_inst_rd(iomem: inst,
423 DEV5G_TX_SIZE256TO511_CNT(tinst)));
424 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size256to511_cnt],
425 val: spx5_inst_rd(iomem: inst,
426 DEV5G_PMAC_TX_SIZE256TO511_CNT(tinst)));
427 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size512to1023_cnt],
428 val: spx5_inst_rd(iomem: inst,
429 DEV5G_TX_SIZE512TO1023_CNT(tinst)));
430 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size512to1023_cnt],
431 val: spx5_inst_rd(iomem: inst,
432 DEV5G_PMAC_TX_SIZE512TO1023_CNT(tinst)));
433 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size1024to1518_cnt],
434 val: spx5_inst_rd(iomem: inst,
435 DEV5G_TX_SIZE1024TO1518_CNT(tinst)));
436 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
437 val: spx5_inst_rd(iomem: inst,
438 DEV5G_PMAC_TX_SIZE1024TO1518_CNT(tinst)));
439 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size1519tomax_cnt],
440 val: spx5_inst_rd(iomem: inst,
441 DEV5G_TX_SIZE1519TOMAX_CNT(tinst)));
442 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
443 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_mm_rx_assembly_err_cnt],
451 val: spx5_inst_rd(iomem: inst,
452 DEV5G_MM_RX_ASSEMBLY_ERR_CNT(tinst)));
453 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_assembly_ok_cnt],
454 val: spx5_inst_rd(iomem: inst,
455 DEV5G_MM_RX_ASSEMBLY_OK_CNT(tinst)));
456 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_merge_frag_cnt],
457 val: spx5_inst_rd(iomem: inst,
458 DEV5G_MM_RX_MERGE_FRAG_CNT(tinst)));
459 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_smd_err_cnt],
460 val: spx5_inst_rd(iomem: inst,
461 DEV5G_MM_RX_SMD_ERR_CNT(tinst)));
462 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_tx_pfragment_cnt],
463 val: spx5_inst_rd(iomem: inst,
464 DEV5G_MM_TX_PFRAGMENT_CNT(tinst)));
465 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_bad_bytes_cnt],
466 val: spx5_inst_rd(iomem: inst,
467 DEV5G_RX_BAD_BYTES_CNT(tinst)));
468 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
469 val: spx5_inst_rd(iomem: inst,
470 DEV5G_PMAC_RX_BAD_BYTES_CNT(tinst)));
471 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_in_bytes_cnt],
472 val: spx5_inst_rd(iomem: inst, DEV5G_RX_IN_BYTES_CNT(tinst)));
473 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_ipg_shrink_cnt],
474 val: spx5_inst_rd(iomem: inst,
475 DEV5G_RX_IPG_SHRINK_CNT(tinst)));
476 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_tagged_frms_cnt],
477 val: spx5_inst_rd(iomem: inst,
478 DEV5G_RX_TAGGED_FRMS_CNT(tinst)));
479 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_untagged_frms_cnt],
480 val: spx5_inst_rd(iomem: inst,
481 DEV5G_RX_UNTAGGED_FRMS_CNT(tinst)));
482 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_out_bytes_cnt],
483 val: spx5_inst_rd(iomem: inst,
484 DEV5G_TX_OUT_BYTES_CNT(tinst)));
485 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_tagged_frms_cnt],
486 val: spx5_inst_rd(iomem: inst,
487 DEV5G_TX_TAGGED_FRMS_CNT(tinst)));
488 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_untagged_frms_cnt],
489 val: spx5_inst_rd(iomem: inst,
490 DEV5G_TX_UNTAGGED_FRMS_CNT(tinst)));
491 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_hih_cksm_err_cnt],
492 val: spx5_inst_rd(iomem: inst,
493 DEV5G_RX_HIH_CKSM_ERR_CNT(tinst)));
494 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_hih_cksm_err_cnt],
495 val: spx5_inst_rd(iomem: inst,
496 DEV5G_PMAC_RX_HIH_CKSM_ERR_CNT(tinst)));
497 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_xgmii_prot_err_cnt],
498 val: spx5_inst_rd(iomem: inst,
499 DEV5G_RX_XGMII_PROT_ERR_CNT(tinst)));
500 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_xgmii_prot_err_cnt],
501 val: spx5_inst_rd(iomem: 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(port: portno);
509 u32 dev = sparx5_to_high_dev(port: portno);
510 void __iomem *inst;
511
512 inst = spx5_inst_get(sparx5, id: 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(cnt: &portstats[spx5_stats_rx_symbol_err_cnt],
524 val: spx5_inst_rd(iomem: inst,
525 ASM_RX_SYMBOL_ERR_CNT(portno)));
526 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_symbol_err_cnt],
527 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_tx_uc_cnt],
535 val: spx5_inst_rd(iomem: inst, ASM_TX_UC_CNT(portno)));
536 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_uc_cnt],
537 val: spx5_inst_rd(iomem: inst, ASM_PMAC_TX_UC_CNT(portno)));
538 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_mc_cnt],
539 val: spx5_inst_rd(iomem: inst, ASM_TX_MC_CNT(portno)));
540 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_bc_cnt],
541 val: spx5_inst_rd(iomem: inst, ASM_TX_BC_CNT(portno)));
542 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_backoff1_cnt],
543 val: spx5_inst_rd(iomem: inst, ASM_TX_BACKOFF1_CNT(portno)));
544 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_multi_coll_cnt],
545 val: spx5_inst_rd(iomem: inst,
546 ASM_TX_MULTI_COLL_CNT(portno)));
547 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_uc_cnt],
548 val: spx5_inst_rd(iomem: inst, ASM_RX_UC_CNT(portno)));
549 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_uc_cnt],
550 val: spx5_inst_rd(iomem: inst, ASM_PMAC_RX_UC_CNT(portno)));
551 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_mc_cnt],
552 val: spx5_inst_rd(iomem: inst, ASM_RX_MC_CNT(portno)));
553 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_bc_cnt],
554 val: spx5_inst_rd(iomem: inst, ASM_RX_BC_CNT(portno)));
555 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_crc_err_cnt],
556 val: spx5_inst_rd(iomem: inst, ASM_RX_CRC_ERR_CNT(portno)));
557 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_crc_err_cnt],
558 val: spx5_inst_rd(iomem: inst,
559 ASM_PMAC_RX_CRC_ERR_CNT(portno)));
560 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_alignment_lost_cnt],
561 val: spx5_inst_rd(iomem: inst,
562 ASM_RX_ALIGNMENT_LOST_CNT(portno)));
563 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
564 val: spx5_inst_rd(iomem: inst,
565 ASM_PMAC_RX_ALIGNMENT_LOST_CNT(portno)));
566 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_ok_bytes_cnt],
567 val: spx5_inst_rd(iomem: inst, ASM_TX_OK_BYTES_CNT(portno)));
568 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
569 val: spx5_inst_rd(iomem: inst,
570 ASM_PMAC_TX_OK_BYTES_CNT(portno)));
571 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_defer_cnt],
572 val: spx5_inst_rd(iomem: inst, ASM_TX_DEFER_CNT(portno)));
573 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_late_coll_cnt],
574 val: spx5_inst_rd(iomem: inst, ASM_TX_LATE_COLL_CNT(portno)));
575 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_xcoll_cnt],
576 val: spx5_inst_rd(iomem: inst, ASM_TX_XCOLL_CNT(portno)));
577 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_csense_cnt],
578 val: spx5_inst_rd(iomem: inst, ASM_TX_CSENSE_CNT(portno)));
579 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_ok_bytes_cnt],
580 val: spx5_inst_rd(iomem: inst, ASM_RX_OK_BYTES_CNT(portno)));
581 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
582 val: spx5_inst_rd(iomem: inst,
583 ASM_PMAC_RX_OK_BYTES_CNT(portno)));
584 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_mc_cnt],
585 val: spx5_inst_rd(iomem: inst, ASM_PMAC_TX_MC_CNT(portno)));
586 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_bc_cnt],
587 val: spx5_inst_rd(iomem: inst, ASM_PMAC_TX_BC_CNT(portno)));
588 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_xdefer_cnt],
589 val: spx5_inst_rd(iomem: inst, ASM_TX_XDEFER_CNT(portno)));
590 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_mc_cnt],
591 val: spx5_inst_rd(iomem: inst, ASM_PMAC_RX_MC_CNT(portno)));
592 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_bc_cnt],
593 val: spx5_inst_rd(iomem: inst, ASM_PMAC_RX_BC_CNT(portno)));
594 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_in_range_len_err_cnt],
595 val: spx5_inst_rd(iomem: inst,
596 ASM_RX_IN_RANGE_LEN_ERR_CNT(portno)));
597 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
598 val: spx5_inst_rd(iomem: inst,
599 ASM_PMAC_RX_IN_RANGE_LEN_ERR_CNT(portno)));
600 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_out_of_range_len_err_cnt],
601 val: spx5_inst_rd(iomem: inst,
602 ASM_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
603 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
604 val: spx5_inst_rd(iomem: inst,
605 ASM_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
606 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_oversize_cnt],
607 val: spx5_inst_rd(iomem: inst, ASM_RX_OVERSIZE_CNT(portno)));
608 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_oversize_cnt],
609 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_tx_pause_cnt],
617 val: spx5_inst_rd(iomem: inst, ASM_TX_PAUSE_CNT(portno)));
618 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_pause_cnt],
619 val: spx5_inst_rd(iomem: inst,
620 ASM_PMAC_TX_PAUSE_CNT(portno)));
621 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_pause_cnt],
622 val: spx5_inst_rd(iomem: inst, ASM_RX_PAUSE_CNT(portno)));
623 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_pause_cnt],
624 val: spx5_inst_rd(iomem: inst,
625 ASM_PMAC_RX_PAUSE_CNT(portno)));
626 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_unsup_opcode_cnt],
627 val: spx5_inst_rd(iomem: inst,
628 ASM_RX_UNSUP_OPCODE_CNT(portno)));
629 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
630 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_rx_undersize_cnt],
638 val: spx5_inst_rd(iomem: inst, ASM_RX_UNDERSIZE_CNT(portno)));
639 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_undersize_cnt],
640 val: spx5_inst_rd(iomem: inst,
641 ASM_PMAC_RX_UNDERSIZE_CNT(portno)));
642 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_oversize_cnt],
643 val: spx5_inst_rd(iomem: inst, ASM_RX_OVERSIZE_CNT(portno)));
644 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_oversize_cnt],
645 val: spx5_inst_rd(iomem: inst,
646 ASM_PMAC_RX_OVERSIZE_CNT(portno)));
647 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_fragments_cnt],
648 val: spx5_inst_rd(iomem: inst, ASM_RX_FRAGMENTS_CNT(portno)));
649 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_fragments_cnt],
650 val: spx5_inst_rd(iomem: inst,
651 ASM_PMAC_RX_FRAGMENTS_CNT(portno)));
652 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_jabbers_cnt],
653 val: spx5_inst_rd(iomem: inst, ASM_RX_JABBERS_CNT(portno)));
654 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_jabbers_cnt],
655 val: spx5_inst_rd(iomem: inst,
656 ASM_PMAC_RX_JABBERS_CNT(portno)));
657 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size64_cnt],
658 val: spx5_inst_rd(iomem: inst, ASM_RX_SIZE64_CNT(portno)));
659 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size64_cnt],
660 val: spx5_inst_rd(iomem: inst,
661 ASM_PMAC_RX_SIZE64_CNT(portno)));
662 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size65to127_cnt],
663 val: spx5_inst_rd(iomem: inst,
664 ASM_RX_SIZE65TO127_CNT(portno)));
665 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size65to127_cnt],
666 val: spx5_inst_rd(iomem: inst,
667 ASM_PMAC_RX_SIZE65TO127_CNT(portno)));
668 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size128to255_cnt],
669 val: spx5_inst_rd(iomem: inst,
670 ASM_RX_SIZE128TO255_CNT(portno)));
671 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size128to255_cnt],
672 val: spx5_inst_rd(iomem: inst,
673 ASM_PMAC_RX_SIZE128TO255_CNT(portno)));
674 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size256to511_cnt],
675 val: spx5_inst_rd(iomem: inst,
676 ASM_RX_SIZE256TO511_CNT(portno)));
677 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size256to511_cnt],
678 val: spx5_inst_rd(iomem: inst,
679 ASM_PMAC_RX_SIZE256TO511_CNT(portno)));
680 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size512to1023_cnt],
681 val: spx5_inst_rd(iomem: inst,
682 ASM_RX_SIZE512TO1023_CNT(portno)));
683 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size512to1023_cnt],
684 val: spx5_inst_rd(iomem: inst,
685 ASM_PMAC_RX_SIZE512TO1023_CNT(portno)));
686 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size1024to1518_cnt],
687 val: spx5_inst_rd(iomem: inst,
688 ASM_RX_SIZE1024TO1518_CNT(portno)));
689 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
690 val: spx5_inst_rd(iomem: inst,
691 ASM_PMAC_RX_SIZE1024TO1518_CNT(portno)));
692 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_size1519tomax_cnt],
693 val: spx5_inst_rd(iomem: inst,
694 ASM_RX_SIZE1519TOMAX_CNT(portno)));
695 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
696 val: spx5_inst_rd(iomem: inst,
697 ASM_PMAC_RX_SIZE1519TOMAX_CNT(portno)));
698 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size64_cnt],
699 val: spx5_inst_rd(iomem: inst, ASM_TX_SIZE64_CNT(portno)));
700 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size64_cnt],
701 val: spx5_inst_rd(iomem: inst,
702 ASM_PMAC_TX_SIZE64_CNT(portno)));
703 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size65to127_cnt],
704 val: spx5_inst_rd(iomem: inst,
705 ASM_TX_SIZE65TO127_CNT(portno)));
706 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size65to127_cnt],
707 val: spx5_inst_rd(iomem: inst,
708 ASM_PMAC_TX_SIZE65TO127_CNT(portno)));
709 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size128to255_cnt],
710 val: spx5_inst_rd(iomem: inst,
711 ASM_TX_SIZE128TO255_CNT(portno)));
712 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size128to255_cnt],
713 val: spx5_inst_rd(iomem: inst,
714 ASM_PMAC_TX_SIZE128TO255_CNT(portno)));
715 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size256to511_cnt],
716 val: spx5_inst_rd(iomem: inst,
717 ASM_TX_SIZE256TO511_CNT(portno)));
718 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size256to511_cnt],
719 val: spx5_inst_rd(iomem: inst,
720 ASM_PMAC_TX_SIZE256TO511_CNT(portno)));
721 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size512to1023_cnt],
722 val: spx5_inst_rd(iomem: inst,
723 ASM_TX_SIZE512TO1023_CNT(portno)));
724 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size512to1023_cnt],
725 val: spx5_inst_rd(iomem: inst,
726 ASM_PMAC_TX_SIZE512TO1023_CNT(portno)));
727 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size1024to1518_cnt],
728 val: spx5_inst_rd(iomem: inst,
729 ASM_TX_SIZE1024TO1518_CNT(portno)));
730 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
731 val: spx5_inst_rd(iomem: inst,
732 ASM_PMAC_TX_SIZE1024TO1518_CNT(portno)));
733 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_size1519tomax_cnt],
734 val: spx5_inst_rd(iomem: inst,
735 ASM_TX_SIZE1519TOMAX_CNT(portno)));
736 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
737 val: spx5_inst_rd(iomem: 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(cnt: &portstats[spx5_stats_mm_rx_assembly_err_cnt],
745 val: spx5_inst_rd(iomem: inst,
746 ASM_MM_RX_ASSEMBLY_ERR_CNT(portno)));
747 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_assembly_ok_cnt],
748 val: spx5_inst_rd(iomem: inst,
749 ASM_MM_RX_ASSEMBLY_OK_CNT(portno)));
750 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_merge_frag_cnt],
751 val: spx5_inst_rd(iomem: inst,
752 ASM_MM_RX_MERGE_FRAG_CNT(portno)));
753 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_rx_smd_err_cnt],
754 val: spx5_inst_rd(iomem: inst,
755 ASM_MM_RX_SMD_ERR_CNT(portno)));
756 sparx5_update_counter(cnt: &portstats[spx5_stats_mm_tx_pfragment_cnt],
757 val: spx5_inst_rd(iomem: inst,
758 ASM_MM_TX_PFRAGMENT_CNT(portno)));
759 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_bad_bytes_cnt],
760 val: spx5_inst_rd(iomem: inst, ASM_RX_BAD_BYTES_CNT(portno)));
761 sparx5_update_counter(cnt: &portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
762 val: spx5_inst_rd(iomem: inst,
763 ASM_PMAC_RX_BAD_BYTES_CNT(portno)));
764 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_in_bytes_cnt],
765 val: spx5_inst_rd(iomem: inst, ASM_RX_IN_BYTES_CNT(portno)));
766 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_ipg_shrink_cnt],
767 val: spx5_inst_rd(iomem: inst,
768 ASM_RX_IPG_SHRINK_CNT(portno)));
769 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_sync_lost_err_cnt],
770 val: spx5_inst_rd(iomem: inst,
771 ASM_RX_SYNC_LOST_ERR_CNT(portno)));
772 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_tagged_frms_cnt],
773 val: spx5_inst_rd(iomem: inst,
774 ASM_RX_TAGGED_FRMS_CNT(portno)));
775 sparx5_update_counter(cnt: &portstats[spx5_stats_rx_untagged_frms_cnt],
776 val: spx5_inst_rd(iomem: inst,
777 ASM_RX_UNTAGGED_FRMS_CNT(portno)));
778 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_out_bytes_cnt],
779 val: spx5_inst_rd(iomem: inst, ASM_TX_OUT_BYTES_CNT(portno)));
780 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_tagged_frms_cnt],
781 val: spx5_inst_rd(iomem: inst,
782 ASM_TX_TAGGED_FRMS_CNT(portno)));
783 sparx5_update_counter(cnt: &portstats[spx5_stats_tx_untagged_frms_cnt],
784 val: spx5_inst_rd(iomem: 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, id: TARGET_ASM, tinst: 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(dev: 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(interface: port->conf.portmode)) {
822 u32 tinst = sparx5_port_dev_index(port: portno);
823 u32 dev = sparx5_to_high_dev(port: portno);
824
825 inst = spx5_inst_get(sparx5, id: dev, tinst);
826 sparx5_get_dev_phy_stats(portstats, inst, tinst);
827 } else {
828 inst = spx5_inst_get(sparx5, id: TARGET_ASM, tinst: 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(dev: 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(interface: port->conf.portmode)) {
847 u32 tinst = sparx5_port_dev_index(port: portno);
848 u32 dev = sparx5_to_high_dev(port: portno);
849
850 inst = spx5_inst_get(sparx5, id: dev, tinst);
851 sparx5_get_dev_mac_stats(portstats, inst, tinst);
852 } else {
853 inst = spx5_inst_get(sparx5, id: TARGET_ASM, tinst: 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(dev: 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(interface: port->conf.portmode)) {
915 u32 tinst = sparx5_port_dev_index(port: portno);
916 u32 dev = sparx5_to_high_dev(port: portno);
917
918 inst = spx5_inst_get(sparx5, id: dev, tinst);
919 sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
920 } else {
921 inst = spx5_inst_get(sparx5, id: TARGET_ASM, tinst: 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(dev: 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(interface: port->conf.portmode)) {
947 u32 tinst = sparx5_port_dev_index(port: portno);
948 u32 dev = sparx5_to_high_dev(port: portno);
949
950 inst = spx5_inst_get(sparx5, id: dev, tinst);
951 sparx5_get_dev_rmon_stats(portstats, inst, tinst);
952 } else {
953 inst = spx5_inst_get(sparx5, id: TARGET_ASM, tinst: 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(dev: 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(dev: 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: &data, str: 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(dev: 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(interface: port->conf.portmode)) {
1030 u32 tinst = sparx5_port_dev_index(port: portno);
1031 u32 dev = sparx5_to_high_dev(port: portno);
1032
1033 inst = spx5_inst_get(sparx5, id: dev, tinst);
1034 sparx5_get_dev_misc_stats(portstats, inst, tinst);
1035 } else {
1036 inst = spx5_inst_get(sparx5, id: TARGET_ASM, tinst: 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(dev: 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(interface: 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, portno: 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(wq: sparx5->stats_queue, dwork: &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(dev: 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(dev: 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, eti: info);
1194
1195 phc = &sparx5->phc[SPARX5_PHC_PORT];
1196
1197 info->phc_index = phc->clock ? ptp_clock_index(ptp: 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(dev: sparx5->dev,
1241 SPX5_PORTS_ALL * sparx5->num_stats,
1242 size: 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(buf: queue_name, size: sizeof(queue_name), fmt: "%s-stats",
1253 dev_name(dev: 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(wq: sparx5->stats_queue, dwork: &sparx5->stats_work,
1260 SPX5_STATS_CHECK_DELAY);
1261
1262 return 0;
1263}
1264

source code of linux/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c