]> Git Repo - J-linux.git/blob - drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[J-linux.git] / drivers / net / ethernet / microchip / lan966x / lan966x_ethtool.c
1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <linux/netdevice.h>
4
5 #include "lan966x_main.h"
6
7 /* Number of traffic classes */
8 #define LAN966X_NUM_TC                  8
9 #define LAN966X_STATS_CHECK_DELAY       (2 * HZ)
10
11 static const struct lan966x_stat_layout lan966x_stats_layout[] = {
12         { .name = "rx_octets", .offset = 0x00, },
13         { .name = "rx_unicast", .offset = 0x01, },
14         { .name = "rx_multicast", .offset = 0x02 },
15         { .name = "rx_broadcast", .offset = 0x03 },
16         { .name = "rx_short", .offset = 0x04 },
17         { .name = "rx_frag", .offset = 0x05 },
18         { .name = "rx_jabber", .offset = 0x06 },
19         { .name = "rx_crc", .offset = 0x07 },
20         { .name = "rx_symbol_err", .offset = 0x08 },
21         { .name = "rx_sz_64", .offset = 0x09 },
22         { .name = "rx_sz_65_127", .offset = 0x0a},
23         { .name = "rx_sz_128_255", .offset = 0x0b},
24         { .name = "rx_sz_256_511", .offset = 0x0c },
25         { .name = "rx_sz_512_1023", .offset = 0x0d },
26         { .name = "rx_sz_1024_1526", .offset = 0x0e },
27         { .name = "rx_sz_jumbo", .offset = 0x0f },
28         { .name = "rx_pause", .offset = 0x10 },
29         { .name = "rx_control", .offset = 0x11 },
30         { .name = "rx_long", .offset = 0x12 },
31         { .name = "rx_cat_drop", .offset = 0x13 },
32         { .name = "rx_red_prio_0", .offset = 0x14 },
33         { .name = "rx_red_prio_1", .offset = 0x15 },
34         { .name = "rx_red_prio_2", .offset = 0x16 },
35         { .name = "rx_red_prio_3", .offset = 0x17 },
36         { .name = "rx_red_prio_4", .offset = 0x18 },
37         { .name = "rx_red_prio_5", .offset = 0x19 },
38         { .name = "rx_red_prio_6", .offset = 0x1a },
39         { .name = "rx_red_prio_7", .offset = 0x1b },
40         { .name = "rx_yellow_prio_0", .offset = 0x1c },
41         { .name = "rx_yellow_prio_1", .offset = 0x1d },
42         { .name = "rx_yellow_prio_2", .offset = 0x1e },
43         { .name = "rx_yellow_prio_3", .offset = 0x1f },
44         { .name = "rx_yellow_prio_4", .offset = 0x20 },
45         { .name = "rx_yellow_prio_5", .offset = 0x21 },
46         { .name = "rx_yellow_prio_6", .offset = 0x22 },
47         { .name = "rx_yellow_prio_7", .offset = 0x23 },
48         { .name = "rx_green_prio_0", .offset = 0x24 },
49         { .name = "rx_green_prio_1", .offset = 0x25 },
50         { .name = "rx_green_prio_2", .offset = 0x26 },
51         { .name = "rx_green_prio_3", .offset = 0x27 },
52         { .name = "rx_green_prio_4", .offset = 0x28 },
53         { .name = "rx_green_prio_5", .offset = 0x29 },
54         { .name = "rx_green_prio_6", .offset = 0x2a },
55         { .name = "rx_green_prio_7", .offset = 0x2b },
56         { .name = "rx_assembly_err", .offset = 0x2c },
57         { .name = "rx_smd_err", .offset = 0x2d },
58         { .name = "rx_assembly_ok", .offset = 0x2e },
59         { .name = "rx_merge_frag", .offset = 0x2f },
60         { .name = "rx_pmac_octets", .offset = 0x30, },
61         { .name = "rx_pmac_unicast", .offset = 0x31, },
62         { .name = "rx_pmac_multicast", .offset = 0x32 },
63         { .name = "rx_pmac_broadcast", .offset = 0x33 },
64         { .name = "rx_pmac_short", .offset = 0x34 },
65         { .name = "rx_pmac_frag", .offset = 0x35 },
66         { .name = "rx_pmac_jabber", .offset = 0x36 },
67         { .name = "rx_pmac_crc", .offset = 0x37 },
68         { .name = "rx_pmac_symbol_err", .offset = 0x38 },
69         { .name = "rx_pmac_sz_64", .offset = 0x39 },
70         { .name = "rx_pmac_sz_65_127", .offset = 0x3a },
71         { .name = "rx_pmac_sz_128_255", .offset = 0x3b },
72         { .name = "rx_pmac_sz_256_511", .offset = 0x3c },
73         { .name = "rx_pmac_sz_512_1023", .offset = 0x3d },
74         { .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },
75         { .name = "rx_pmac_sz_jumbo", .offset = 0x3f },
76         { .name = "rx_pmac_pause", .offset = 0x40 },
77         { .name = "rx_pmac_control", .offset = 0x41 },
78         { .name = "rx_pmac_long", .offset = 0x42 },
79
80         { .name = "tx_octets", .offset = 0x80, },
81         { .name = "tx_unicast", .offset = 0x81, },
82         { .name = "tx_multicast", .offset = 0x82 },
83         { .name = "tx_broadcast", .offset = 0x83 },
84         { .name = "tx_col", .offset = 0x84 },
85         { .name = "tx_drop", .offset = 0x85 },
86         { .name = "tx_pause", .offset = 0x86 },
87         { .name = "tx_sz_64", .offset = 0x87 },
88         { .name = "tx_sz_65_127", .offset = 0x88 },
89         { .name = "tx_sz_128_255", .offset = 0x89 },
90         { .name = "tx_sz_256_511", .offset = 0x8a },
91         { .name = "tx_sz_512_1023", .offset = 0x8b },
92         { .name = "tx_sz_1024_1526", .offset = 0x8c },
93         { .name = "tx_sz_jumbo", .offset = 0x8d },
94         { .name = "tx_yellow_prio_0", .offset = 0x8e },
95         { .name = "tx_yellow_prio_1", .offset = 0x8f },
96         { .name = "tx_yellow_prio_2", .offset = 0x90 },
97         { .name = "tx_yellow_prio_3", .offset = 0x91 },
98         { .name = "tx_yellow_prio_4", .offset = 0x92 },
99         { .name = "tx_yellow_prio_5", .offset = 0x93 },
100         { .name = "tx_yellow_prio_6", .offset = 0x94 },
101         { .name = "tx_yellow_prio_7", .offset = 0x95 },
102         { .name = "tx_green_prio_0", .offset = 0x96 },
103         { .name = "tx_green_prio_1", .offset = 0x97 },
104         { .name = "tx_green_prio_2", .offset = 0x98 },
105         { .name = "tx_green_prio_3", .offset = 0x99 },
106         { .name = "tx_green_prio_4", .offset = 0x9a },
107         { .name = "tx_green_prio_5", .offset = 0x9b },
108         { .name = "tx_green_prio_6", .offset = 0x9c },
109         { .name = "tx_green_prio_7", .offset = 0x9d },
110         { .name = "tx_aged", .offset = 0x9e },
111         { .name = "tx_llct", .offset = 0x9f },
112         { .name = "tx_ct", .offset = 0xa0 },
113         { .name = "tx_mm_hold", .offset = 0xa1 },
114         { .name = "tx_merge_frag", .offset = 0xa2 },
115         { .name = "tx_pmac_octets", .offset = 0xa3, },
116         { .name = "tx_pmac_unicast", .offset = 0xa4, },
117         { .name = "tx_pmac_multicast", .offset = 0xa5 },
118         { .name = "tx_pmac_broadcast", .offset = 0xa6 },
119         { .name = "tx_pmac_pause", .offset = 0xa7 },
120         { .name = "tx_pmac_sz_64", .offset = 0xa8 },
121         { .name = "tx_pmac_sz_65_127", .offset = 0xa9 },
122         { .name = "tx_pmac_sz_128_255", .offset = 0xaa },
123         { .name = "tx_pmac_sz_256_511", .offset = 0xab },
124         { .name = "tx_pmac_sz_512_1023", .offset = 0xac },
125         { .name = "tx_pmac_sz_1024_1526", .offset = 0xad },
126         { .name = "tx_pmac_sz_jumbo", .offset = 0xae },
127
128         { .name = "dr_local", .offset = 0x100 },
129         { .name = "dr_tail", .offset = 0x101 },
130         { .name = "dr_yellow_prio_0", .offset = 0x102 },
131         { .name = "dr_yellow_prio_1", .offset = 0x103 },
132         { .name = "dr_yellow_prio_2", .offset = 0x104 },
133         { .name = "dr_yellow_prio_3", .offset = 0x105 },
134         { .name = "dr_yellow_prio_4", .offset = 0x106 },
135         { .name = "dr_yellow_prio_5", .offset = 0x107 },
136         { .name = "dr_yellow_prio_6", .offset = 0x108 },
137         { .name = "dr_yellow_prio_7", .offset = 0x109 },
138         { .name = "dr_green_prio_0", .offset = 0x10a },
139         { .name = "dr_green_prio_1", .offset = 0x10b },
140         { .name = "dr_green_prio_2", .offset = 0x10c },
141         { .name = "dr_green_prio_3", .offset = 0x10d },
142         { .name = "dr_green_prio_4", .offset = 0x10e },
143         { .name = "dr_green_prio_5", .offset = 0x10f },
144         { .name = "dr_green_prio_6", .offset = 0x110 },
145         { .name = "dr_green_prio_7", .offset = 0x111 },
146 };
147
148 /* The following numbers are indexes into lan966x_stats_layout[] */
149 #define SYS_COUNT_RX_OCT                  0
150 #define SYS_COUNT_RX_UC                   1
151 #define SYS_COUNT_RX_MC                   2
152 #define SYS_COUNT_RX_BC                   3
153 #define SYS_COUNT_RX_SHORT                4
154 #define SYS_COUNT_RX_FRAG                 5
155 #define SYS_COUNT_RX_JABBER               6
156 #define SYS_COUNT_RX_CRC                  7
157 #define SYS_COUNT_RX_SYMBOL_ERR           8
158 #define SYS_COUNT_RX_SZ_64                9
159 #define SYS_COUNT_RX_SZ_65_127           10
160 #define SYS_COUNT_RX_SZ_128_255          11
161 #define SYS_COUNT_RX_SZ_256_511          12
162 #define SYS_COUNT_RX_SZ_512_1023         13
163 #define SYS_COUNT_RX_SZ_1024_1526        14
164 #define SYS_COUNT_RX_SZ_JUMBO            15
165 #define SYS_COUNT_RX_PAUSE               16
166 #define SYS_COUNT_RX_CONTROL             17
167 #define SYS_COUNT_RX_LONG                18
168 #define SYS_COUNT_RX_CAT_DROP            19
169 #define SYS_COUNT_RX_RED_PRIO_0          20
170 #define SYS_COUNT_RX_RED_PRIO_1          21
171 #define SYS_COUNT_RX_RED_PRIO_2          22
172 #define SYS_COUNT_RX_RED_PRIO_3          23
173 #define SYS_COUNT_RX_RED_PRIO_4          24
174 #define SYS_COUNT_RX_RED_PRIO_5          25
175 #define SYS_COUNT_RX_RED_PRIO_6          26
176 #define SYS_COUNT_RX_RED_PRIO_7          27
177 #define SYS_COUNT_RX_YELLOW_PRIO_0       28
178 #define SYS_COUNT_RX_YELLOW_PRIO_1       29
179 #define SYS_COUNT_RX_YELLOW_PRIO_2       30
180 #define SYS_COUNT_RX_YELLOW_PRIO_3       31
181 #define SYS_COUNT_RX_YELLOW_PRIO_4       32
182 #define SYS_COUNT_RX_YELLOW_PRIO_5       33
183 #define SYS_COUNT_RX_YELLOW_PRIO_6       34
184 #define SYS_COUNT_RX_YELLOW_PRIO_7       35
185 #define SYS_COUNT_RX_GREEN_PRIO_0        36
186 #define SYS_COUNT_RX_GREEN_PRIO_1        37
187 #define SYS_COUNT_RX_GREEN_PRIO_2        38
188 #define SYS_COUNT_RX_GREEN_PRIO_3        39
189 #define SYS_COUNT_RX_GREEN_PRIO_4        40
190 #define SYS_COUNT_RX_GREEN_PRIO_5        41
191 #define SYS_COUNT_RX_GREEN_PRIO_6        42
192 #define SYS_COUNT_RX_GREEN_PRIO_7        43
193 #define SYS_COUNT_RX_ASSEMBLY_ERR        44
194 #define SYS_COUNT_RX_SMD_ERR             45
195 #define SYS_COUNT_RX_ASSEMBLY_OK         46
196 #define SYS_COUNT_RX_MERGE_FRAG          47
197 #define SYS_COUNT_RX_PMAC_OCT            48
198 #define SYS_COUNT_RX_PMAC_UC             49
199 #define SYS_COUNT_RX_PMAC_MC             50
200 #define SYS_COUNT_RX_PMAC_BC             51
201 #define SYS_COUNT_RX_PMAC_SHORT          52
202 #define SYS_COUNT_RX_PMAC_FRAG           53
203 #define SYS_COUNT_RX_PMAC_JABBER         54
204 #define SYS_COUNT_RX_PMAC_CRC            55
205 #define SYS_COUNT_RX_PMAC_SYMBOL_ERR     56
206 #define SYS_COUNT_RX_PMAC_SZ_64          57
207 #define SYS_COUNT_RX_PMAC_SZ_65_127      58
208 #define SYS_COUNT_RX_PMAC_SZ_128_255     59
209 #define SYS_COUNT_RX_PMAC_SZ_256_511     60
210 #define SYS_COUNT_RX_PMAC_SZ_512_1023    61
211 #define SYS_COUNT_RX_PMAC_SZ_1024_1526   62
212 #define SYS_COUNT_RX_PMAC_SZ_JUMBO       63
213 #define SYS_COUNT_RX_PMAC_PAUSE          64
214 #define SYS_COUNT_RX_PMAC_CONTROL        65
215 #define SYS_COUNT_RX_PMAC_LONG           66
216
217 #define SYS_COUNT_TX_OCT                 67
218 #define SYS_COUNT_TX_UC                  68
219 #define SYS_COUNT_TX_MC                  69
220 #define SYS_COUNT_TX_BC                  70
221 #define SYS_COUNT_TX_COL                 71
222 #define SYS_COUNT_TX_DROP                72
223 #define SYS_COUNT_TX_PAUSE               73
224 #define SYS_COUNT_TX_SZ_64               74
225 #define SYS_COUNT_TX_SZ_65_127           75
226 #define SYS_COUNT_TX_SZ_128_255          76
227 #define SYS_COUNT_TX_SZ_256_511          77
228 #define SYS_COUNT_TX_SZ_512_1023         78
229 #define SYS_COUNT_TX_SZ_1024_1526        79
230 #define SYS_COUNT_TX_SZ_JUMBO            80
231 #define SYS_COUNT_TX_YELLOW_PRIO_0       81
232 #define SYS_COUNT_TX_YELLOW_PRIO_1       82
233 #define SYS_COUNT_TX_YELLOW_PRIO_2       83
234 #define SYS_COUNT_TX_YELLOW_PRIO_3       84
235 #define SYS_COUNT_TX_YELLOW_PRIO_4       85
236 #define SYS_COUNT_TX_YELLOW_PRIO_5       86
237 #define SYS_COUNT_TX_YELLOW_PRIO_6       87
238 #define SYS_COUNT_TX_YELLOW_PRIO_7       88
239 #define SYS_COUNT_TX_GREEN_PRIO_0        89
240 #define SYS_COUNT_TX_GREEN_PRIO_1        90
241 #define SYS_COUNT_TX_GREEN_PRIO_2        91
242 #define SYS_COUNT_TX_GREEN_PRIO_3        92
243 #define SYS_COUNT_TX_GREEN_PRIO_4        93
244 #define SYS_COUNT_TX_GREEN_PRIO_5        94
245 #define SYS_COUNT_TX_GREEN_PRIO_6        95
246 #define SYS_COUNT_TX_GREEN_PRIO_7        96
247 #define SYS_COUNT_TX_AGED                97
248 #define SYS_COUNT_TX_LLCT                98
249 #define SYS_COUNT_TX_CT                  99
250 #define SYS_COUNT_TX_MM_HOLD            100
251 #define SYS_COUNT_TX_MERGE_FRAG         101
252 #define SYS_COUNT_TX_PMAC_OCT           102
253 #define SYS_COUNT_TX_PMAC_UC            103
254 #define SYS_COUNT_TX_PMAC_MC            104
255 #define SYS_COUNT_TX_PMAC_BC            105
256 #define SYS_COUNT_TX_PMAC_PAUSE         106
257 #define SYS_COUNT_TX_PMAC_SZ_64         107
258 #define SYS_COUNT_TX_PMAC_SZ_65_127     108
259 #define SYS_COUNT_TX_PMAC_SZ_128_255    109
260 #define SYS_COUNT_TX_PMAC_SZ_256_511    110
261 #define SYS_COUNT_TX_PMAC_SZ_512_1023   111
262 #define SYS_COUNT_TX_PMAC_SZ_1024_1526  112
263 #define SYS_COUNT_TX_PMAC_SZ_JUMBO      113
264
265 #define SYS_COUNT_DR_LOCAL              114
266 #define SYS_COUNT_DR_TAIL               115
267 #define SYS_COUNT_DR_YELLOW_PRIO_0      116
268 #define SYS_COUNT_DR_YELLOW_PRIO_1      117
269 #define SYS_COUNT_DR_YELLOW_PRIO_2      118
270 #define SYS_COUNT_DR_YELLOW_PRIO_3      119
271 #define SYS_COUNT_DR_YELLOW_PRIO_4      120
272 #define SYS_COUNT_DR_YELLOW_PRIO_5      121
273 #define SYS_COUNT_DR_YELLOW_PRIO_6      122
274 #define SYS_COUNT_DR_YELLOW_PRIO_7      123
275 #define SYS_COUNT_DR_GREEN_PRIO_0       124
276 #define SYS_COUNT_DR_GREEN_PRIO_1       125
277 #define SYS_COUNT_DR_GREEN_PRIO_2       126
278 #define SYS_COUNT_DR_GREEN_PRIO_3       127
279 #define SYS_COUNT_DR_GREEN_PRIO_4       128
280 #define SYS_COUNT_DR_GREEN_PRIO_5       129
281 #define SYS_COUNT_DR_GREEN_PRIO_6       130
282 #define SYS_COUNT_DR_GREEN_PRIO_7       131
283
284 /* Add a possibly wrapping 32 bit value to a 64 bit counter */
285 static void lan966x_add_cnt(u64 *cnt, u32 val)
286 {
287         if (val < (*cnt & U32_MAX))
288                 *cnt += (u64)1 << 32; /* value has wrapped */
289
290         *cnt = (*cnt & ~(u64)U32_MAX) + val;
291 }
292
293 static void lan966x_stats_update(struct lan966x *lan966x)
294 {
295         int i, j;
296
297         mutex_lock(&lan966x->stats_lock);
298
299         for (i = 0; i < lan966x->num_phys_ports; i++) {
300                 uint idx = i * lan966x->num_stats;
301
302                 lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),
303                        lan966x, SYS_STAT_CFG);
304
305                 for (j = 0; j < lan966x->num_stats; j++) {
306                         u32 offset = lan966x->stats_layout[j].offset;
307
308                         lan966x_add_cnt(&lan966x->stats[idx++],
309                                         lan_rd(lan966x, SYS_CNT(offset)));
310                 }
311         }
312
313         mutex_unlock(&lan966x->stats_lock);
314 }
315
316 static int lan966x_get_sset_count(struct net_device *dev, int sset)
317 {
318         struct lan966x_port *port = netdev_priv(dev);
319         struct lan966x *lan966x = port->lan966x;
320
321         if (sset != ETH_SS_STATS)
322                 return -EOPNOTSUPP;
323
324         return lan966x->num_stats;
325 }
326
327 static void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)
328 {
329         struct lan966x_port *port = netdev_priv(netdev);
330         struct lan966x *lan966x = port->lan966x;
331         int i;
332
333         if (sset != ETH_SS_STATS)
334                 return;
335
336         for (i = 0; i < lan966x->num_stats; i++)
337                 memcpy(data + i * ETH_GSTRING_LEN,
338                        lan966x->stats_layout[i].name, ETH_GSTRING_LEN);
339 }
340
341 static void lan966x_get_ethtool_stats(struct net_device *dev,
342                                       struct ethtool_stats *stats, u64 *data)
343 {
344         struct lan966x_port *port = netdev_priv(dev);
345         struct lan966x *lan966x = port->lan966x;
346         int i;
347
348         /* check and update now */
349         lan966x_stats_update(lan966x);
350
351         /* Copy all counters */
352         for (i = 0; i < lan966x->num_stats; i++)
353                 *data++ = lan966x->stats[port->chip_port *
354                                          lan966x->num_stats + i];
355 }
356
357 static void lan966x_get_eth_mac_stats(struct net_device *dev,
358                                       struct ethtool_eth_mac_stats *mac_stats)
359 {
360         struct lan966x_port *port = netdev_priv(dev);
361         struct lan966x *lan966x = port->lan966x;
362         u32 idx;
363
364         lan966x_stats_update(lan966x);
365
366         idx = port->chip_port * lan966x->num_stats;
367
368         mutex_lock(&lan966x->stats_lock);
369
370         mac_stats->FramesTransmittedOK =
371                 lan966x->stats[idx + SYS_COUNT_TX_UC] +
372                 lan966x->stats[idx + SYS_COUNT_TX_MC] +
373                 lan966x->stats[idx + SYS_COUNT_TX_BC] +
374                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +
375                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +
376                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
377         mac_stats->SingleCollisionFrames =
378                 lan966x->stats[idx + SYS_COUNT_TX_COL];
379         mac_stats->MultipleCollisionFrames = 0;
380         mac_stats->FramesReceivedOK =
381                 lan966x->stats[idx + SYS_COUNT_RX_UC] +
382                 lan966x->stats[idx + SYS_COUNT_RX_MC] +
383                 lan966x->stats[idx + SYS_COUNT_RX_BC];
384         mac_stats->FrameCheckSequenceErrors =
385                 lan966x->stats[idx + SYS_COUNT_RX_CRC] +
386                 lan966x->stats[idx + SYS_COUNT_RX_CRC];
387         mac_stats->AlignmentErrors = 0;
388         mac_stats->OctetsTransmittedOK =
389                 lan966x->stats[idx + SYS_COUNT_TX_OCT] +
390                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
391         mac_stats->FramesWithDeferredXmissions =
392                 lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];
393         mac_stats->LateCollisions = 0;
394         mac_stats->FramesAbortedDueToXSColls = 0;
395         mac_stats->FramesLostDueToIntMACXmitError = 0;
396         mac_stats->CarrierSenseErrors = 0;
397         mac_stats->OctetsReceivedOK =
398                 lan966x->stats[idx + SYS_COUNT_RX_OCT];
399         mac_stats->FramesLostDueToIntMACRcvError = 0;
400         mac_stats->MulticastFramesXmittedOK =
401                 lan966x->stats[idx + SYS_COUNT_TX_MC] +
402                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];
403         mac_stats->BroadcastFramesXmittedOK =
404                 lan966x->stats[idx + SYS_COUNT_TX_BC] +
405                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
406         mac_stats->FramesWithExcessiveDeferral = 0;
407         mac_stats->MulticastFramesReceivedOK =
408                 lan966x->stats[idx + SYS_COUNT_RX_MC];
409         mac_stats->BroadcastFramesReceivedOK =
410                 lan966x->stats[idx + SYS_COUNT_RX_BC];
411         mac_stats->InRangeLengthErrors =
412                 lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
413                 lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
414                 lan966x->stats[idx + SYS_COUNT_RX_CRC] +
415                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
416                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
417                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];
418         mac_stats->OutOfRangeLengthField =
419                 lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
420                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
421                 lan966x->stats[idx + SYS_COUNT_RX_LONG] +
422                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
423         mac_stats->FrameTooLongErrors =
424                 lan966x->stats[idx + SYS_COUNT_RX_LONG] +
425                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
426
427         mutex_unlock(&lan966x->stats_lock);
428 }
429
430 static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
431         {    0,    64 },
432         {   65,   127 },
433         {  128,   255 },
434         {  256,   511 },
435         {  512,  1023 },
436         { 1024,  1518 },
437         { 1519, 10239 },
438         {}
439 };
440
441 static void lan966x_get_eth_rmon_stats(struct net_device *dev,
442                                        struct ethtool_rmon_stats *rmon_stats,
443                                        const struct ethtool_rmon_hist_range **ranges)
444 {
445         struct lan966x_port *port = netdev_priv(dev);
446         struct lan966x *lan966x = port->lan966x;
447         u32 idx;
448
449         lan966x_stats_update(lan966x);
450
451         idx = port->chip_port * lan966x->num_stats;
452
453         mutex_lock(&lan966x->stats_lock);
454
455         rmon_stats->undersize_pkts =
456                 lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
457                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];
458         rmon_stats->oversize_pkts =
459                 lan966x->stats[idx + SYS_COUNT_RX_LONG] +
460                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
461         rmon_stats->fragments =
462                 lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
463                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];
464         rmon_stats->jabbers =
465                 lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
466                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];
467         rmon_stats->hist[0] =
468                 lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
469                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];
470         rmon_stats->hist[1] =
471                 lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
472                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];
473         rmon_stats->hist[2] =
474                 lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
475                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];
476         rmon_stats->hist[3] =
477                 lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
478                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];
479         rmon_stats->hist[4] =
480                 lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
481                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];
482         rmon_stats->hist[5] =
483                 lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
484                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
485         rmon_stats->hist[6] =
486                 lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
487                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
488
489         rmon_stats->hist_tx[0] =
490                 lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
491                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];
492         rmon_stats->hist_tx[1] =
493                 lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
494                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];
495         rmon_stats->hist_tx[2] =
496                 lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
497                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];
498         rmon_stats->hist_tx[3] =
499                 lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
500                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];
501         rmon_stats->hist_tx[4] =
502                 lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
503                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];
504         rmon_stats->hist_tx[5] =
505                 lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
506                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
507         rmon_stats->hist_tx[6] =
508                 lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
509                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
510
511         mutex_unlock(&lan966x->stats_lock);
512
513         *ranges = lan966x_rmon_ranges;
514 }
515
516 static int lan966x_get_link_ksettings(struct net_device *ndev,
517                                       struct ethtool_link_ksettings *cmd)
518 {
519         struct lan966x_port *port = netdev_priv(ndev);
520
521         return phylink_ethtool_ksettings_get(port->phylink, cmd);
522 }
523
524 static int lan966x_set_link_ksettings(struct net_device *ndev,
525                                       const struct ethtool_link_ksettings *cmd)
526 {
527         struct lan966x_port *port = netdev_priv(ndev);
528
529         return phylink_ethtool_ksettings_set(port->phylink, cmd);
530 }
531
532 static void lan966x_get_pauseparam(struct net_device *dev,
533                                    struct ethtool_pauseparam *pause)
534 {
535         struct lan966x_port *port = netdev_priv(dev);
536
537         phylink_ethtool_get_pauseparam(port->phylink, pause);
538 }
539
540 static int lan966x_set_pauseparam(struct net_device *dev,
541                                   struct ethtool_pauseparam *pause)
542 {
543         struct lan966x_port *port = netdev_priv(dev);
544
545         return phylink_ethtool_set_pauseparam(port->phylink, pause);
546 }
547
548 static int lan966x_get_ts_info(struct net_device *dev,
549                                struct ethtool_ts_info *info)
550 {
551         struct lan966x_port *port = netdev_priv(dev);
552         struct lan966x *lan966x = port->lan966x;
553         struct lan966x_phc *phc;
554
555         if (!lan966x->ptp)
556                 return ethtool_op_get_ts_info(dev, info);
557
558         phc = &lan966x->phc[LAN966X_PHC_PORT];
559
560         info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
561         if (info->phc_index == -1) {
562                 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
563                                          SOF_TIMESTAMPING_RX_SOFTWARE |
564                                          SOF_TIMESTAMPING_SOFTWARE;
565                 return 0;
566         }
567         info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
568                                  SOF_TIMESTAMPING_RX_SOFTWARE |
569                                  SOF_TIMESTAMPING_SOFTWARE |
570                                  SOF_TIMESTAMPING_TX_HARDWARE |
571                                  SOF_TIMESTAMPING_RX_HARDWARE |
572                                  SOF_TIMESTAMPING_RAW_HARDWARE;
573         info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
574                          BIT(HWTSTAMP_TX_ONESTEP_SYNC);
575         info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
576                            BIT(HWTSTAMP_FILTER_ALL);
577
578         return 0;
579 }
580
581 const struct ethtool_ops lan966x_ethtool_ops = {
582         .get_link_ksettings     = lan966x_get_link_ksettings,
583         .set_link_ksettings     = lan966x_set_link_ksettings,
584         .get_pauseparam         = lan966x_get_pauseparam,
585         .set_pauseparam         = lan966x_set_pauseparam,
586         .get_sset_count         = lan966x_get_sset_count,
587         .get_strings            = lan966x_get_strings,
588         .get_ethtool_stats      = lan966x_get_ethtool_stats,
589         .get_eth_mac_stats      = lan966x_get_eth_mac_stats,
590         .get_rmon_stats         = lan966x_get_eth_rmon_stats,
591         .get_link               = ethtool_op_get_link,
592         .get_ts_info            = lan966x_get_ts_info,
593 };
594
595 static void lan966x_check_stats_work(struct work_struct *work)
596 {
597         struct delayed_work *del_work = to_delayed_work(work);
598         struct lan966x *lan966x = container_of(del_work, struct lan966x,
599                                                stats_work);
600
601         lan966x_stats_update(lan966x);
602
603         queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
604                            LAN966X_STATS_CHECK_DELAY);
605 }
606
607 void lan966x_stats_get(struct net_device *dev,
608                        struct rtnl_link_stats64 *stats)
609 {
610         struct lan966x_port *port = netdev_priv(dev);
611         struct lan966x *lan966x = port->lan966x;
612         u32 idx;
613         int i;
614
615         idx = port->chip_port * lan966x->num_stats;
616
617         mutex_lock(&lan966x->stats_lock);
618
619         stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
620                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];
621
622         stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
623                 lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
624                 lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
625                 lan966x->stats[idx + SYS_COUNT_RX_CRC] +
626                 lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
627                 lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
628                 lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
629                 lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
630                 lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
631                 lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
632                 lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
633                 lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +
634                 lan966x->stats[idx + SYS_COUNT_RX_LONG] +
635                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
636                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
637                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
638                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +
639                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +
640                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +
641                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +
642                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +
643                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +
644                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];
645
646         stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +
647                 lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];
648
649         stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
650                 lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
651                 lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
652                 lan966x->stats[idx + SYS_COUNT_RX_CRC] +
653                 lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
654                 lan966x->stats[idx + SYS_COUNT_RX_LONG];
655
656         stats->rx_dropped = dev->stats.rx_dropped +
657                 lan966x->stats[idx + SYS_COUNT_RX_LONG] +
658                 lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
659                 lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
660                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
661                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
662                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
663                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
664                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
665                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
666                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
667                 lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
668
669         for (i = 0; i < LAN966X_NUM_TC; i++) {
670                 stats->rx_dropped +=
671                         (lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +
672                          lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);
673         }
674
675         /* Get Tx stats */
676         stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +
677                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
678
679         stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
680                 lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
681                 lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
682                 lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
683                 lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
684                 lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
685                 lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +
686                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +
687                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +
688                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +
689                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +
690                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +
691                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +
692                 lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];
693
694         stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +
695                 lan966x->stats[idx + SYS_COUNT_TX_AGED];
696
697         stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];
698
699         mutex_unlock(&lan966x->stats_lock);
700 }
701
702 int lan966x_stats_init(struct lan966x *lan966x)
703 {
704         char queue_name[32];
705
706         lan966x->stats_layout = lan966x_stats_layout;
707         lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);
708         lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *
709                                       lan966x->num_stats,
710                                       sizeof(u64), GFP_KERNEL);
711         if (!lan966x->stats)
712                 return -ENOMEM;
713
714         /* Init stats worker */
715         mutex_init(&lan966x->stats_lock);
716         snprintf(queue_name, sizeof(queue_name), "%s-stats",
717                  dev_name(lan966x->dev));
718         lan966x->stats_queue = create_singlethread_workqueue(queue_name);
719         if (!lan966x->stats_queue)
720                 return -ENOMEM;
721
722         INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
723         queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
724                            LAN966X_STATS_CHECK_DELAY);
725
726         return 0;
727 }
This page took 0.07171 seconds and 4 git commands to generate.