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(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 | |
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(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 | |
239 | static 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 | |
250 | static 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 | |
317 | static 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 | |
338 | static 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 | |
447 | static 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 | |
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(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 | |
520 | static 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 | |
531 | static 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 | |
613 | static 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 | |
634 | static 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 | |
741 | static 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 | |
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, 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 | |
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(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 | |
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(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 | |
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(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 | |
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(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 | |
995 | static 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 | |
1005 | static 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 | |
1018 | static 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 | |
1048 | void 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 | |
1111 | static 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 | |
1121 | static 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 | |
1130 | static 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 | |
1143 | static 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 | |
1151 | static 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 | |
1159 | static 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 | |
1168 | static 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 | |
1185 | static 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 | |
1218 | const 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 | |
1232 | int 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 | |