]> Git Repo - linux.git/blob - drivers/net/dsa/sja1105/sja1105_ethtool.c
Linux 6.14-rc3
[linux.git] / drivers / net / dsa / sja1105 / sja1105_ethtool.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018-2019, Vladimir Oltean <[email protected]>
3  */
4 #include "sja1105.h"
5
6 enum sja1105_counter_index {
7         __SJA1105_COUNTER_UNUSED,
8         /* MAC */
9         N_RUNT,
10         N_SOFERR,
11         N_ALIGNERR,
12         N_MIIERR,
13         TYPEERR,
14         SIZEERR,
15         TCTIMEOUT,
16         PRIORERR,
17         NOMASTER,
18         MEMOV,
19         MEMERR,
20         INVTYP,
21         INTCYOV,
22         DOMERR,
23         PCFBAGDROP,
24         SPCPRIOR,
25         AGEPRIOR,
26         PORTDROP,
27         LENDROP,
28         BAGDROP,
29         POLICEERR,
30         DRPNONA664ERR,
31         SPCERR,
32         AGEDRP,
33         /* HL1 */
34         N_N664ERR,
35         N_VLANERR,
36         N_UNRELEASED,
37         N_SIZEERR,
38         N_CRCERR,
39         N_VLNOTFOUND,
40         N_CTPOLERR,
41         N_POLERR,
42         N_RXFRM,
43         N_RXBYTE,
44         N_TXFRM,
45         N_TXBYTE,
46         /* HL2 */
47         N_QFULL,
48         N_PART_DROP,
49         N_EGR_DISABLED,
50         N_NOT_REACH,
51         __MAX_SJA1105ET_PORT_COUNTER,
52         /* P/Q/R/S only */
53         /* ETHER */
54         N_DROPS_NOLEARN = __MAX_SJA1105ET_PORT_COUNTER,
55         N_DROPS_NOROUTE,
56         N_DROPS_ILL_DTAG,
57         N_DROPS_DTAG,
58         N_DROPS_SOTAG,
59         N_DROPS_SITAG,
60         N_DROPS_UTAG,
61         N_TX_BYTES_1024_2047,
62         N_TX_BYTES_512_1023,
63         N_TX_BYTES_256_511,
64         N_TX_BYTES_128_255,
65         N_TX_BYTES_65_127,
66         N_TX_BYTES_64,
67         N_TX_MCAST,
68         N_TX_BCAST,
69         N_RX_BYTES_1024_2047,
70         N_RX_BYTES_512_1023,
71         N_RX_BYTES_256_511,
72         N_RX_BYTES_128_255,
73         N_RX_BYTES_65_127,
74         N_RX_BYTES_64,
75         N_RX_MCAST,
76         N_RX_BCAST,
77         __MAX_SJA1105PQRS_PORT_COUNTER,
78 };
79
80 struct sja1105_port_counter {
81         enum sja1105_stats_area area;
82         const char name[ETH_GSTRING_LEN];
83         int offset;
84         int start;
85         int end;
86         bool is_64bit;
87 };
88
89 static const struct sja1105_port_counter sja1105_port_counters[] = {
90         /* MAC-Level Diagnostic Counters */
91         [N_RUNT] = {
92                 .area = MAC,
93                 .name = "n_runt",
94                 .offset = 0,
95                 .start = 31,
96                 .end = 24,
97         },
98         [N_SOFERR] = {
99                 .area = MAC,
100                 .name = "n_soferr",
101                 .offset = 0x0,
102                 .start = 23,
103                 .end = 16,
104         },
105         [N_ALIGNERR] = {
106                 .area = MAC,
107                 .name = "n_alignerr",
108                 .offset = 0x0,
109                 .start = 15,
110                 .end = 8,
111         },
112         [N_MIIERR] = {
113                 .area = MAC,
114                 .name = "n_miierr",
115                 .offset = 0x0,
116                 .start = 7,
117                 .end = 0,
118         },
119         /* MAC-Level Diagnostic Flags */
120         [TYPEERR] = {
121                 .area = MAC,
122                 .name = "typeerr",
123                 .offset = 0x1,
124                 .start = 27,
125                 .end = 27,
126         },
127         [SIZEERR] = {
128                 .area = MAC,
129                 .name = "sizeerr",
130                 .offset = 0x1,
131                 .start = 26,
132                 .end = 26,
133         },
134         [TCTIMEOUT] = {
135                 .area = MAC,
136                 .name = "tctimeout",
137                 .offset = 0x1,
138                 .start = 25,
139                 .end = 25,
140         },
141         [PRIORERR] = {
142                 .area = MAC,
143                 .name = "priorerr",
144                 .offset = 0x1,
145                 .start = 24,
146                 .end = 24,
147         },
148         [NOMASTER] = {
149                 .area = MAC,
150                 .name = "nomaster",
151                 .offset = 0x1,
152                 .start = 23,
153                 .end = 23,
154         },
155         [MEMOV] = {
156                 .area = MAC,
157                 .name = "memov",
158                 .offset = 0x1,
159                 .start = 22,
160                 .end = 22,
161         },
162         [MEMERR] = {
163                 .area = MAC,
164                 .name = "memerr",
165                 .offset = 0x1,
166                 .start = 21,
167                 .end = 21,
168         },
169         [INVTYP] = {
170                 .area = MAC,
171                 .name = "invtyp",
172                 .offset = 0x1,
173                 .start = 19,
174                 .end = 19,
175         },
176         [INTCYOV] = {
177                 .area = MAC,
178                 .name = "intcyov",
179                 .offset = 0x1,
180                 .start = 18,
181                 .end = 18,
182         },
183         [DOMERR] = {
184                 .area = MAC,
185                 .name = "domerr",
186                 .offset = 0x1,
187                 .start = 17,
188                 .end = 17,
189         },
190         [PCFBAGDROP] = {
191                 .area = MAC,
192                 .name = "pcfbagdrop",
193                 .offset = 0x1,
194                 .start = 16,
195                 .end = 16,
196         },
197         [SPCPRIOR] = {
198                 .area = MAC,
199                 .name = "spcprior",
200                 .offset = 0x1,
201                 .start = 15,
202                 .end = 12,
203         },
204         [AGEPRIOR] = {
205                 .area = MAC,
206                 .name = "ageprior",
207                 .offset = 0x1,
208                 .start = 11,
209                 .end = 8,
210         },
211         [PORTDROP] = {
212                 .area = MAC,
213                 .name = "portdrop",
214                 .offset = 0x1,
215                 .start = 6,
216                 .end = 6,
217         },
218         [LENDROP] = {
219                 .area = MAC,
220                 .name = "lendrop",
221                 .offset = 0x1,
222                 .start = 5,
223                 .end = 5,
224         },
225         [BAGDROP] = {
226                 .area = MAC,
227                 .name = "bagdrop",
228                 .offset = 0x1,
229                 .start = 4,
230                 .end = 4,
231         },
232         [POLICEERR] = {
233                 .area = MAC,
234                 .name = "policeerr",
235                 .offset = 0x1,
236                 .start = 3,
237                 .end = 3,
238         },
239         [DRPNONA664ERR] = {
240                 .area = MAC,
241                 .name = "drpnona664err",
242                 .offset = 0x1,
243                 .start = 2,
244                 .end = 2,
245         },
246         [SPCERR] = {
247                 .area = MAC,
248                 .name = "spcerr",
249                 .offset = 0x1,
250                 .start = 1,
251                 .end = 1,
252         },
253         [AGEDRP] = {
254                 .area = MAC,
255                 .name = "agedrp",
256                 .offset = 0x1,
257                 .start = 0,
258                 .end = 0,
259         },
260         /* High-Level Diagnostic Counters */
261         [N_N664ERR] = {
262                 .area = HL1,
263                 .name = "n_n664err",
264                 .offset = 0xF,
265                 .start = 31,
266                 .end = 0,
267         },
268         [N_VLANERR] = {
269                 .area = HL1,
270                 .name = "n_vlanerr",
271                 .offset = 0xE,
272                 .start = 31,
273                 .end = 0,
274         },
275         [N_UNRELEASED] = {
276                 .area = HL1,
277                 .name = "n_unreleased",
278                 .offset = 0xD,
279                 .start = 31,
280                 .end = 0,
281         },
282         [N_SIZEERR] = {
283                 .area = HL1,
284                 .name = "n_sizeerr",
285                 .offset = 0xC,
286                 .start = 31,
287                 .end = 0,
288         },
289         [N_CRCERR] = {
290                 .area = HL1,
291                 .name = "n_crcerr",
292                 .offset = 0xB,
293                 .start = 31,
294                 .end = 0,
295         },
296         [N_VLNOTFOUND] = {
297                 .area = HL1,
298                 .name = "n_vlnotfound",
299                 .offset = 0xA,
300                 .start = 31,
301                 .end = 0,
302         },
303         [N_CTPOLERR] = {
304                 .area = HL1,
305                 .name = "n_ctpolerr",
306                 .offset = 0x9,
307                 .start = 31,
308                 .end = 0,
309         },
310         [N_POLERR] = {
311                 .area = HL1,
312                 .name = "n_polerr",
313                 .offset = 0x8,
314                 .start = 31,
315                 .end = 0,
316         },
317         [N_RXFRM] = {
318                 .area = HL1,
319                 .name = "n_rxfrm",
320                 .offset = 0x6,
321                 .start = 31,
322                 .end = 0,
323                 .is_64bit = true,
324         },
325         [N_RXBYTE] = {
326                 .area = HL1,
327                 .name = "n_rxbyte",
328                 .offset = 0x4,
329                 .start = 31,
330                 .end = 0,
331                 .is_64bit = true,
332         },
333         [N_TXFRM] = {
334                 .area = HL1,
335                 .name = "n_txfrm",
336                 .offset = 0x2,
337                 .start = 31,
338                 .end = 0,
339                 .is_64bit = true,
340         },
341         [N_TXBYTE] = {
342                 .area = HL1,
343                 .name = "n_txbyte",
344                 .offset = 0x0,
345                 .start = 31,
346                 .end = 0,
347                 .is_64bit = true,
348         },
349         [N_QFULL] = {
350                 .area = HL2,
351                 .name = "n_qfull",
352                 .offset = 0x3,
353                 .start = 31,
354                 .end = 0,
355         },
356         [N_PART_DROP] = {
357                 .area = HL2,
358                 .name = "n_part_drop",
359                 .offset = 0x2,
360                 .start = 31,
361                 .end = 0,
362         },
363         [N_EGR_DISABLED] = {
364                 .area = HL2,
365                 .name = "n_egr_disabled",
366                 .offset = 0x1,
367                 .start = 31,
368                 .end = 0,
369         },
370         [N_NOT_REACH] = {
371                 .area = HL2,
372                 .name = "n_not_reach",
373                 .offset = 0x0,
374                 .start = 31,
375                 .end = 0,
376         },
377         /* Ether Stats */
378         [N_DROPS_NOLEARN] = {
379                 .area = ETHER,
380                 .name = "n_drops_nolearn",
381                 .offset = 0x16,
382                 .start = 31,
383                 .end = 0,
384         },
385         [N_DROPS_NOROUTE] = {
386                 .area = ETHER,
387                 .name = "n_drops_noroute",
388                 .offset = 0x15,
389                 .start = 31,
390                 .end = 0,
391         },
392         [N_DROPS_ILL_DTAG] = {
393                 .area = ETHER,
394                 .name = "n_drops_ill_dtag",
395                 .offset = 0x14,
396                 .start = 31,
397                 .end = 0,
398         },
399         [N_DROPS_DTAG] = {
400                 .area = ETHER,
401                 .name = "n_drops_dtag",
402                 .offset = 0x13,
403                 .start = 31,
404                 .end = 0,
405         },
406         [N_DROPS_SOTAG] = {
407                 .area = ETHER,
408                 .name = "n_drops_sotag",
409                 .offset = 0x12,
410                 .start = 31,
411                 .end = 0,
412         },
413         [N_DROPS_SITAG] = {
414                 .area = ETHER,
415                 .name = "n_drops_sitag",
416                 .offset = 0x11,
417                 .start = 31,
418                 .end = 0,
419         },
420         [N_DROPS_UTAG] = {
421                 .area = ETHER,
422                 .name = "n_drops_utag",
423                 .offset = 0x10,
424                 .start = 31,
425                 .end = 0,
426         },
427         [N_TX_BYTES_1024_2047] = {
428                 .area = ETHER,
429                 .name = "n_tx_bytes_1024_2047",
430                 .offset = 0x0F,
431                 .start = 31,
432                 .end = 0,
433         },
434         [N_TX_BYTES_512_1023] = {
435                 .area = ETHER,
436                 .name = "n_tx_bytes_512_1023",
437                 .offset = 0x0E,
438                 .start = 31,
439                 .end = 0,
440         },
441         [N_TX_BYTES_256_511] = {
442                 .area = ETHER,
443                 .name = "n_tx_bytes_256_511",
444                 .offset = 0x0D,
445                 .start = 31,
446                 .end = 0,
447         },
448         [N_TX_BYTES_128_255] = {
449                 .area = ETHER,
450                 .name = "n_tx_bytes_128_255",
451                 .offset = 0x0C,
452                 .start = 31,
453                 .end = 0,
454         },
455         [N_TX_BYTES_65_127] = {
456                 .area = ETHER,
457                 .name = "n_tx_bytes_65_127",
458                 .offset = 0x0B,
459                 .start = 31,
460                 .end = 0,
461         },
462         [N_TX_BYTES_64] = {
463                 .area = ETHER,
464                 .name = "n_tx_bytes_64",
465                 .offset = 0x0A,
466                 .start = 31,
467                 .end = 0,
468         },
469         [N_TX_MCAST] = {
470                 .area = ETHER,
471                 .name = "n_tx_mcast",
472                 .offset = 0x09,
473                 .start = 31,
474                 .end = 0,
475         },
476         [N_TX_BCAST] = {
477                 .area = ETHER,
478                 .name = "n_tx_bcast",
479                 .offset = 0x08,
480                 .start = 31,
481                 .end = 0,
482         },
483         [N_RX_BYTES_1024_2047] = {
484                 .area = ETHER,
485                 .name = "n_rx_bytes_1024_2047",
486                 .offset = 0x07,
487                 .start = 31,
488                 .end = 0,
489         },
490         [N_RX_BYTES_512_1023] = {
491                 .area = ETHER,
492                 .name = "n_rx_bytes_512_1023",
493                 .offset = 0x06,
494                 .start = 31,
495                 .end = 0,
496         },
497         [N_RX_BYTES_256_511] = {
498                 .area = ETHER,
499                 .name = "n_rx_bytes_256_511",
500                 .offset = 0x05,
501                 .start = 31,
502                 .end = 0,
503         },
504         [N_RX_BYTES_128_255] = {
505                 .area = ETHER,
506                 .name = "n_rx_bytes_128_255",
507                 .offset = 0x04,
508                 .start = 31,
509                 .end = 0,
510         },
511         [N_RX_BYTES_65_127] = {
512                 .area = ETHER,
513                 .name = "n_rx_bytes_65_127",
514                 .offset = 0x03,
515                 .start = 31,
516                 .end = 0,
517         },
518         [N_RX_BYTES_64] = {
519                 .area = ETHER,
520                 .name = "n_rx_bytes_64",
521                 .offset = 0x02,
522                 .start = 31,
523                 .end = 0,
524         },
525         [N_RX_MCAST] = {
526                 .area = ETHER,
527                 .name = "n_rx_mcast",
528                 .offset = 0x01,
529                 .start = 31,
530                 .end = 0,
531         },
532         [N_RX_BCAST] = {
533                 .area = ETHER,
534                 .name = "n_rx_bcast",
535                 .offset = 0x00,
536                 .start = 31,
537                 .end = 0,
538         },
539 };
540
541 static int sja1105_port_counter_read(struct sja1105_private *priv, int port,
542                                      enum sja1105_counter_index idx, u64 *ctr)
543 {
544         const struct sja1105_port_counter *c = &sja1105_port_counters[idx];
545         size_t size = c->is_64bit ? 8 : 4;
546         u8 buf[8] = {0};
547         u64 regs;
548         int rc;
549
550         regs = priv->info->regs->stats[c->area][port];
551
552         rc = sja1105_xfer_buf(priv, SPI_READ, regs + c->offset, buf, size);
553         if (rc)
554                 return rc;
555
556         sja1105_unpack(buf, ctr, c->start, c->end, size);
557
558         return 0;
559 }
560
561 void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
562 {
563         struct sja1105_private *priv = ds->priv;
564         enum sja1105_counter_index max_ctr, i;
565         int rc, k = 0;
566
567         if (priv->info->device_id == SJA1105E_DEVICE_ID ||
568             priv->info->device_id == SJA1105T_DEVICE_ID)
569                 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
570         else
571                 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
572
573         for (i = 0; i < max_ctr; i++) {
574                 rc = sja1105_port_counter_read(priv, port, i, &data[k++]);
575                 if (rc) {
576                         dev_err(ds->dev,
577                                 "Failed to read port %d counters: %d\n",
578                                 port, rc);
579                         break;
580                 }
581         }
582 }
583
584 void sja1105_get_strings(struct dsa_switch *ds, int port,
585                          u32 stringset, u8 *data)
586 {
587         struct sja1105_private *priv = ds->priv;
588         enum sja1105_counter_index max_ctr, i;
589
590         if (stringset != ETH_SS_STATS)
591                 return;
592
593         if (priv->info->device_id == SJA1105E_DEVICE_ID ||
594             priv->info->device_id == SJA1105T_DEVICE_ID)
595                 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
596         else
597                 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
598
599         for (i = 0; i < max_ctr; i++)
600                 ethtool_puts(&data, sja1105_port_counters[i].name);
601 }
602
603 int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset)
604 {
605         struct sja1105_private *priv = ds->priv;
606         enum sja1105_counter_index max_ctr, i;
607         int sset_count = 0;
608
609         if (sset != ETH_SS_STATS)
610                 return -EOPNOTSUPP;
611
612         if (priv->info->device_id == SJA1105E_DEVICE_ID ||
613             priv->info->device_id == SJA1105T_DEVICE_ID)
614                 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
615         else
616                 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
617
618         for (i = 0; i < max_ctr; i++) {
619                 if (!strlen(sja1105_port_counters[i].name))
620                         continue;
621
622                 sset_count++;
623         }
624
625         return sset_count;
626 }
This page took 0.09681 seconds and 4 git commands to generate.