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