1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3  * Microsemi Ocelot Switch driver
4  *
5  * Copyright (c) 2017 Microsemi Corporation
6  */
7 #include <linux/dsa/ocelot.h>
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/of_net.h>
11 #include <linux/netdevice.h>
12 #include <linux/phylink.h>
13 #include <linux/of_mdio.h>
14 #include <linux/of_platform.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/skbuff.h>
17 #include <net/switchdev.h>
18 
19 #include <soc/mscc/ocelot_vcap.h>
20 #include <soc/mscc/ocelot_hsio.h>
21 #include <soc/mscc/vsc7514_regs.h>
22 #include "ocelot_fdma.h"
23 #include "ocelot.h"
24 
25 #define VSC7514_VCAP_POLICER_BASE			128
26 #define VSC7514_VCAP_POLICER_MAX			191
27 
28 static const u32 *ocelot_regmap[TARGET_MAX] = {
29 	[ANA] = vsc7514_ana_regmap,
30 	[QS] = vsc7514_qs_regmap,
31 	[QSYS] = vsc7514_qsys_regmap,
32 	[REW] = vsc7514_rew_regmap,
33 	[SYS] = vsc7514_sys_regmap,
34 	[S0] = vsc7514_vcap_regmap,
35 	[S1] = vsc7514_vcap_regmap,
36 	[S2] = vsc7514_vcap_regmap,
37 	[PTP] = vsc7514_ptp_regmap,
38 	[DEV_GMII] = vsc7514_dev_gmii_regmap,
39 };
40 
41 static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
42 	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11),
43 	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10),
44 	[ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27),
45 	[ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26),
46 	[ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25),
47 	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
48 	[ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23),
49 	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
50 	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
51 	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
52 	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
53 	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
54 	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
55 	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
56 	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
57 	[ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14),
58 	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
59 	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
60 	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
61 	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
62 	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
63 	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
64 	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
65 	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
66 	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
67 	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
68 	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
69 	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
70 	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
71 	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
72 	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18),
73 	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11),
74 	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9),
75 	[QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20),
76 	[QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19),
77 	[QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7),
78 	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3),
79 	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0),
80 	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2),
81 	[SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1),
82 	[SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0),
83 	/* Replicated per number of ports (12), register size 4 per port */
84 	[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4),
85 	[QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4),
86 	[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4),
87 	[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4),
88 	[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4),
89 	[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4),
90 	[SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4),
91 	[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4),
92 	[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4),
93 	[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4),
94 	[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4),
95 	[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4),
96 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
97 };
98 
99 static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
100 	[OCELOT_STAT_RX_OCTETS] = {
101 		.name = "rx_octets",
102 		.reg = SYS_COUNT_RX_OCTETS,
103 	},
104 	[OCELOT_STAT_RX_UNICAST] = {
105 		.name = "rx_unicast",
106 		.reg = SYS_COUNT_RX_UNICAST,
107 	},
108 	[OCELOT_STAT_RX_MULTICAST] = {
109 		.name = "rx_multicast",
110 		.reg = SYS_COUNT_RX_MULTICAST,
111 	},
112 	[OCELOT_STAT_RX_BROADCAST] = {
113 		.name = "rx_broadcast",
114 		.reg = SYS_COUNT_RX_BROADCAST,
115 	},
116 	[OCELOT_STAT_RX_SHORTS] = {
117 		.name = "rx_shorts",
118 		.reg = SYS_COUNT_RX_SHORTS,
119 	},
120 	[OCELOT_STAT_RX_FRAGMENTS] = {
121 		.name = "rx_fragments",
122 		.reg = SYS_COUNT_RX_FRAGMENTS,
123 	},
124 	[OCELOT_STAT_RX_JABBERS] = {
125 		.name = "rx_jabbers",
126 		.reg = SYS_COUNT_RX_JABBERS,
127 	},
128 	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
129 		.name = "rx_crc_align_errs",
130 		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
131 	},
132 	[OCELOT_STAT_RX_SYM_ERRS] = {
133 		.name = "rx_sym_errs",
134 		.reg = SYS_COUNT_RX_SYM_ERRS,
135 	},
136 	[OCELOT_STAT_RX_64] = {
137 		.name = "rx_frames_below_65_octets",
138 		.reg = SYS_COUNT_RX_64,
139 	},
140 	[OCELOT_STAT_RX_65_127] = {
141 		.name = "rx_frames_65_to_127_octets",
142 		.reg = SYS_COUNT_RX_65_127,
143 	},
144 	[OCELOT_STAT_RX_128_255] = {
145 		.name = "rx_frames_128_to_255_octets",
146 		.reg = SYS_COUNT_RX_128_255,
147 	},
148 	[OCELOT_STAT_RX_256_511] = {
149 		.name = "rx_frames_256_to_511_octets",
150 		.reg = SYS_COUNT_RX_256_511,
151 	},
152 	[OCELOT_STAT_RX_512_1023] = {
153 		.name = "rx_frames_512_to_1023_octets",
154 		.reg = SYS_COUNT_RX_512_1023,
155 	},
156 	[OCELOT_STAT_RX_1024_1526] = {
157 		.name = "rx_frames_1024_to_1526_octets",
158 		.reg = SYS_COUNT_RX_1024_1526,
159 	},
160 	[OCELOT_STAT_RX_1527_MAX] = {
161 		.name = "rx_frames_over_1526_octets",
162 		.reg = SYS_COUNT_RX_1527_MAX,
163 	},
164 	[OCELOT_STAT_RX_PAUSE] = {
165 		.name = "rx_pause",
166 		.reg = SYS_COUNT_RX_PAUSE,
167 	},
168 	[OCELOT_STAT_RX_CONTROL] = {
169 		.name = "rx_control",
170 		.reg = SYS_COUNT_RX_CONTROL,
171 	},
172 	[OCELOT_STAT_RX_LONGS] = {
173 		.name = "rx_longs",
174 		.reg = SYS_COUNT_RX_LONGS,
175 	},
176 	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
177 		.name = "rx_classified_drops",
178 		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
179 	},
180 	[OCELOT_STAT_RX_RED_PRIO_0] = {
181 		.name = "rx_red_prio_0",
182 		.reg = SYS_COUNT_RX_RED_PRIO_0,
183 	},
184 	[OCELOT_STAT_RX_RED_PRIO_1] = {
185 		.name = "rx_red_prio_1",
186 		.reg = SYS_COUNT_RX_RED_PRIO_1,
187 	},
188 	[OCELOT_STAT_RX_RED_PRIO_2] = {
189 		.name = "rx_red_prio_2",
190 		.reg = SYS_COUNT_RX_RED_PRIO_2,
191 	},
192 	[OCELOT_STAT_RX_RED_PRIO_3] = {
193 		.name = "rx_red_prio_3",
194 		.reg = SYS_COUNT_RX_RED_PRIO_3,
195 	},
196 	[OCELOT_STAT_RX_RED_PRIO_4] = {
197 		.name = "rx_red_prio_4",
198 		.reg = SYS_COUNT_RX_RED_PRIO_4,
199 	},
200 	[OCELOT_STAT_RX_RED_PRIO_5] = {
201 		.name = "rx_red_prio_5",
202 		.reg = SYS_COUNT_RX_RED_PRIO_5,
203 	},
204 	[OCELOT_STAT_RX_RED_PRIO_6] = {
205 		.name = "rx_red_prio_6",
206 		.reg = SYS_COUNT_RX_RED_PRIO_6,
207 	},
208 	[OCELOT_STAT_RX_RED_PRIO_7] = {
209 		.name = "rx_red_prio_7",
210 		.reg = SYS_COUNT_RX_RED_PRIO_7,
211 	},
212 	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
213 		.name = "rx_yellow_prio_0",
214 		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
215 	},
216 	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
217 		.name = "rx_yellow_prio_1",
218 		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
219 	},
220 	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
221 		.name = "rx_yellow_prio_2",
222 		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
223 	},
224 	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
225 		.name = "rx_yellow_prio_3",
226 		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
227 	},
228 	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
229 		.name = "rx_yellow_prio_4",
230 		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
231 	},
232 	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
233 		.name = "rx_yellow_prio_5",
234 		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
235 	},
236 	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
237 		.name = "rx_yellow_prio_6",
238 		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
239 	},
240 	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
241 		.name = "rx_yellow_prio_7",
242 		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
243 	},
244 	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
245 		.name = "rx_green_prio_0",
246 		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
247 	},
248 	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
249 		.name = "rx_green_prio_1",
250 		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
251 	},
252 	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
253 		.name = "rx_green_prio_2",
254 		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
255 	},
256 	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
257 		.name = "rx_green_prio_3",
258 		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
259 	},
260 	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
261 		.name = "rx_green_prio_4",
262 		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
263 	},
264 	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
265 		.name = "rx_green_prio_5",
266 		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
267 	},
268 	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
269 		.name = "rx_green_prio_6",
270 		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
271 	},
272 	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
273 		.name = "rx_green_prio_7",
274 		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
275 	},
276 	[OCELOT_STAT_TX_OCTETS] = {
277 		.name = "tx_octets",
278 		.reg = SYS_COUNT_TX_OCTETS,
279 	},
280 	[OCELOT_STAT_TX_UNICAST] = {
281 		.name = "tx_unicast",
282 		.reg = SYS_COUNT_TX_UNICAST,
283 	},
284 	[OCELOT_STAT_TX_MULTICAST] = {
285 		.name = "tx_multicast",
286 		.reg = SYS_COUNT_TX_MULTICAST,
287 	},
288 	[OCELOT_STAT_TX_BROADCAST] = {
289 		.name = "tx_broadcast",
290 		.reg = SYS_COUNT_TX_BROADCAST,
291 	},
292 	[OCELOT_STAT_TX_COLLISION] = {
293 		.name = "tx_collision",
294 		.reg = SYS_COUNT_TX_COLLISION,
295 	},
296 	[OCELOT_STAT_TX_DROPS] = {
297 		.name = "tx_drops",
298 		.reg = SYS_COUNT_TX_DROPS,
299 	},
300 	[OCELOT_STAT_TX_PAUSE] = {
301 		.name = "tx_pause",
302 		.reg = SYS_COUNT_TX_PAUSE,
303 	},
304 	[OCELOT_STAT_TX_64] = {
305 		.name = "tx_frames_below_65_octets",
306 		.reg = SYS_COUNT_TX_64,
307 	},
308 	[OCELOT_STAT_TX_65_127] = {
309 		.name = "tx_frames_65_to_127_octets",
310 		.reg = SYS_COUNT_TX_65_127,
311 	},
312 	[OCELOT_STAT_TX_128_255] = {
313 		.name = "tx_frames_128_255_octets",
314 		.reg = SYS_COUNT_TX_128_255,
315 	},
316 	[OCELOT_STAT_TX_256_511] = {
317 		.name = "tx_frames_256_511_octets",
318 		.reg = SYS_COUNT_TX_256_511,
319 	},
320 	[OCELOT_STAT_TX_512_1023] = {
321 		.name = "tx_frames_512_1023_octets",
322 		.reg = SYS_COUNT_TX_512_1023,
323 	},
324 	[OCELOT_STAT_TX_1024_1526] = {
325 		.name = "tx_frames_1024_1526_octets",
326 		.reg = SYS_COUNT_TX_1024_1526,
327 	},
328 	[OCELOT_STAT_TX_1527_MAX] = {
329 		.name = "tx_frames_over_1526_octets",
330 		.reg = SYS_COUNT_TX_1527_MAX,
331 	},
332 	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
333 		.name = "tx_yellow_prio_0",
334 		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
335 	},
336 	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
337 		.name = "tx_yellow_prio_1",
338 		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
339 	},
340 	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
341 		.name = "tx_yellow_prio_2",
342 		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
343 	},
344 	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
345 		.name = "tx_yellow_prio_3",
346 		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
347 	},
348 	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
349 		.name = "tx_yellow_prio_4",
350 		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
351 	},
352 	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
353 		.name = "tx_yellow_prio_5",
354 		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
355 	},
356 	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
357 		.name = "tx_yellow_prio_6",
358 		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
359 	},
360 	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
361 		.name = "tx_yellow_prio_7",
362 		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
363 	},
364 	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
365 		.name = "tx_green_prio_0",
366 		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
367 	},
368 	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
369 		.name = "tx_green_prio_1",
370 		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
371 	},
372 	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
373 		.name = "tx_green_prio_2",
374 		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
375 	},
376 	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
377 		.name = "tx_green_prio_3",
378 		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
379 	},
380 	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
381 		.name = "tx_green_prio_4",
382 		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
383 	},
384 	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
385 		.name = "tx_green_prio_5",
386 		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
387 	},
388 	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
389 		.name = "tx_green_prio_6",
390 		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
391 	},
392 	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
393 		.name = "tx_green_prio_7",
394 		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
395 	},
396 	[OCELOT_STAT_TX_AGED] = {
397 		.name = "tx_aged",
398 		.reg = SYS_COUNT_TX_AGING,
399 	},
400 	[OCELOT_STAT_DROP_LOCAL] = {
401 		.name = "drop_local",
402 		.reg = SYS_COUNT_DROP_LOCAL,
403 	},
404 	[OCELOT_STAT_DROP_TAIL] = {
405 		.name = "drop_tail",
406 		.reg = SYS_COUNT_DROP_TAIL,
407 	},
408 	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
409 		.name = "drop_yellow_prio_0",
410 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
411 	},
412 	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
413 		.name = "drop_yellow_prio_1",
414 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
415 	},
416 	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
417 		.name = "drop_yellow_prio_2",
418 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
419 	},
420 	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
421 		.name = "drop_yellow_prio_3",
422 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
423 	},
424 	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
425 		.name = "drop_yellow_prio_4",
426 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
427 	},
428 	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
429 		.name = "drop_yellow_prio_5",
430 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
431 	},
432 	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
433 		.name = "drop_yellow_prio_6",
434 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
435 	},
436 	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
437 		.name = "drop_yellow_prio_7",
438 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
439 	},
440 	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
441 		.name = "drop_green_prio_0",
442 		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
443 	},
444 	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
445 		.name = "drop_green_prio_1",
446 		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
447 	},
448 	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
449 		.name = "drop_green_prio_2",
450 		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
451 	},
452 	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
453 		.name = "drop_green_prio_3",
454 		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
455 	},
456 	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
457 		.name = "drop_green_prio_4",
458 		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
459 	},
460 	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
461 		.name = "drop_green_prio_5",
462 		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
463 	},
464 	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
465 		.name = "drop_green_prio_6",
466 		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
467 	},
468 	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
469 		.name = "drop_green_prio_7",
470 		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
471 	},
472 };
473 
474 static void ocelot_pll5_init(struct ocelot *ocelot)
475 {
476 	/* Configure PLL5. This will need a proper CCF driver
477 	 * The values are coming from the VTSS API for Ocelot
478 	 */
479 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4,
480 		     HSIO_PLL5G_CFG4_IB_CTRL(0x7600) |
481 		     HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8));
482 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0,
483 		     HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) |
484 		     HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) |
485 		     HSIO_PLL5G_CFG0_ENA_BIAS |
486 		     HSIO_PLL5G_CFG0_ENA_VCO_BUF |
487 		     HSIO_PLL5G_CFG0_ENA_CP1 |
488 		     HSIO_PLL5G_CFG0_SELCPI(2) |
489 		     HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) |
490 		     HSIO_PLL5G_CFG0_SELBGV820(4) |
491 		     HSIO_PLL5G_CFG0_DIV4 |
492 		     HSIO_PLL5G_CFG0_ENA_CLKTREE |
493 		     HSIO_PLL5G_CFG0_ENA_LANE);
494 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2,
495 		     HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET |
496 		     HSIO_PLL5G_CFG2_EN_RESET_OVERRUN |
497 		     HSIO_PLL5G_CFG2_GAIN_TEST(0x8) |
498 		     HSIO_PLL5G_CFG2_ENA_AMPCTRL |
499 		     HSIO_PLL5G_CFG2_PWD_AMPCTRL_N |
500 		     HSIO_PLL5G_CFG2_AMPC_SEL(0x10));
501 }
502 
503 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
504 {
505 	int ret;
506 
507 	ocelot->map = ocelot_regmap;
508 	ocelot->stats_layout = ocelot_stats_layout;
509 	ocelot->num_mact_rows = 1024;
510 	ocelot->ops = ops;
511 
512 	ret = ocelot_regfields_init(ocelot, ocelot_regfields);
513 	if (ret)
514 		return ret;
515 
516 	ocelot_pll5_init(ocelot);
517 
518 	eth_random_addr(ocelot->base_mac);
519 	ocelot->base_mac[5] &= 0xf0;
520 
521 	return 0;
522 }
523 
524 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
525 {
526 	struct ocelot *ocelot = arg;
527 	int grp = 0, err;
528 
529 	while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) {
530 		struct sk_buff *skb;
531 
532 		err = ocelot_xtr_poll_frame(ocelot, grp, &skb);
533 		if (err)
534 			goto out;
535 
536 		skb->dev->stats.rx_bytes += skb->len;
537 		skb->dev->stats.rx_packets++;
538 
539 		if (!skb_defer_rx_timestamp(skb))
540 			netif_rx(skb);
541 	}
542 
543 out:
544 	if (err < 0)
545 		ocelot_drain_cpu_queue(ocelot, 0);
546 
547 	return IRQ_HANDLED;
548 }
549 
550 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
551 {
552 	struct ocelot *ocelot = arg;
553 
554 	ocelot_get_txtstamp(ocelot);
555 
556 	return IRQ_HANDLED;
557 }
558 
559 static const struct of_device_id mscc_ocelot_match[] = {
560 	{ .compatible = "mscc,vsc7514-switch" },
561 	{ }
562 };
563 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
564 
565 static int ocelot_reset(struct ocelot *ocelot)
566 {
567 	int retries = 100;
568 	u32 val;
569 
570 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
571 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
572 
573 	do {
574 		msleep(1);
575 		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
576 				  &val);
577 	} while (val && --retries);
578 
579 	if (!retries)
580 		return -ETIMEDOUT;
581 
582 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
583 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
584 
585 	return 0;
586 }
587 
588 /* Watermark encode
589  * Bit 8:   Unit; 0:1, 1:16
590  * Bit 7-0: Value to be multiplied with unit
591  */
592 static u16 ocelot_wm_enc(u16 value)
593 {
594 	WARN_ON(value >= 16 * BIT(8));
595 
596 	if (value >= BIT(8))
597 		return BIT(8) | (value / 16);
598 
599 	return value;
600 }
601 
602 static u16 ocelot_wm_dec(u16 wm)
603 {
604 	if (wm & BIT(8))
605 		return (wm & GENMASK(7, 0)) * 16;
606 
607 	return wm;
608 }
609 
610 static void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
611 {
612 	*inuse = (val & GENMASK(23, 12)) >> 12;
613 	*maxuse = val & GENMASK(11, 0);
614 }
615 
616 static const struct ocelot_ops ocelot_ops = {
617 	.reset			= ocelot_reset,
618 	.wm_enc			= ocelot_wm_enc,
619 	.wm_dec			= ocelot_wm_dec,
620 	.wm_stat		= ocelot_wm_stat,
621 	.port_to_netdev		= ocelot_port_to_netdev,
622 	.netdev_to_port		= ocelot_netdev_to_port,
623 };
624 
625 static struct vcap_props vsc7514_vcap_props[] = {
626 	[VCAP_ES0] = {
627 		.action_type_width = 0,
628 		.action_table = {
629 			[ES0_ACTION_TYPE_NORMAL] = {
630 				.width = 73, /* HIT_STICKY not included */
631 				.count = 1,
632 			},
633 		},
634 		.target = S0,
635 		.keys = vsc7514_vcap_es0_keys,
636 		.actions = vsc7514_vcap_es0_actions,
637 	},
638 	[VCAP_IS1] = {
639 		.action_type_width = 0,
640 		.action_table = {
641 			[IS1_ACTION_TYPE_NORMAL] = {
642 				.width = 78, /* HIT_STICKY not included */
643 				.count = 4,
644 			},
645 		},
646 		.target = S1,
647 		.keys = vsc7514_vcap_is1_keys,
648 		.actions = vsc7514_vcap_is1_actions,
649 	},
650 	[VCAP_IS2] = {
651 		.action_type_width = 1,
652 		.action_table = {
653 			[IS2_ACTION_TYPE_NORMAL] = {
654 				.width = 49,
655 				.count = 2
656 			},
657 			[IS2_ACTION_TYPE_SMAC_SIP] = {
658 				.width = 6,
659 				.count = 4
660 			},
661 		},
662 		.target = S2,
663 		.keys = vsc7514_vcap_is2_keys,
664 		.actions = vsc7514_vcap_is2_actions,
665 	},
666 };
667 
668 static struct ptp_clock_info ocelot_ptp_clock_info = {
669 	.owner		= THIS_MODULE,
670 	.name		= "ocelot ptp",
671 	.max_adj	= 0x7fffffff,
672 	.n_alarm	= 0,
673 	.n_ext_ts	= 0,
674 	.n_per_out	= OCELOT_PTP_PINS_NUM,
675 	.n_pins		= OCELOT_PTP_PINS_NUM,
676 	.pps		= 0,
677 	.gettime64	= ocelot_ptp_gettime64,
678 	.settime64	= ocelot_ptp_settime64,
679 	.adjtime	= ocelot_ptp_adjtime,
680 	.adjfine	= ocelot_ptp_adjfine,
681 	.verify		= ocelot_ptp_verify,
682 	.enable		= ocelot_ptp_enable,
683 };
684 
685 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot)
686 {
687 	int port;
688 
689 	for (port = 0; port < ocelot->num_phys_ports; port++)
690 		ocelot_port_devlink_teardown(ocelot, port);
691 }
692 
693 static void mscc_ocelot_release_ports(struct ocelot *ocelot)
694 {
695 	int port;
696 
697 	for (port = 0; port < ocelot->num_phys_ports; port++) {
698 		struct ocelot_port *ocelot_port;
699 
700 		ocelot_port = ocelot->ports[port];
701 		if (!ocelot_port)
702 			continue;
703 
704 		ocelot_deinit_port(ocelot, port);
705 		ocelot_release_port(ocelot_port);
706 	}
707 }
708 
709 static int mscc_ocelot_init_ports(struct platform_device *pdev,
710 				  struct device_node *ports)
711 {
712 	struct ocelot *ocelot = platform_get_drvdata(pdev);
713 	u32 devlink_ports_registered = 0;
714 	struct device_node *portnp;
715 	int port, err;
716 	u32 reg;
717 
718 	ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
719 				     sizeof(struct ocelot_port *), GFP_KERNEL);
720 	if (!ocelot->ports)
721 		return -ENOMEM;
722 
723 	ocelot->devlink_ports = devm_kcalloc(ocelot->dev,
724 					     ocelot->num_phys_ports,
725 					     sizeof(*ocelot->devlink_ports),
726 					     GFP_KERNEL);
727 	if (!ocelot->devlink_ports)
728 		return -ENOMEM;
729 
730 	for_each_available_child_of_node(ports, portnp) {
731 		struct ocelot_port_private *priv;
732 		struct ocelot_port *ocelot_port;
733 		struct devlink_port *dlp;
734 		struct regmap *target;
735 		struct resource *res;
736 		char res_name[8];
737 
738 		if (of_property_read_u32(portnp, "reg", &reg))
739 			continue;
740 
741 		port = reg;
742 		if (port < 0 || port >= ocelot->num_phys_ports) {
743 			dev_err(ocelot->dev,
744 				"invalid port number: %d >= %d\n", port,
745 				ocelot->num_phys_ports);
746 			continue;
747 		}
748 
749 		snprintf(res_name, sizeof(res_name), "port%d", port);
750 
751 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
752 						   res_name);
753 		target = ocelot_regmap_init(ocelot, res);
754 		if (IS_ERR(target)) {
755 			err = PTR_ERR(target);
756 			of_node_put(portnp);
757 			goto out_teardown;
758 		}
759 
760 		err = ocelot_port_devlink_init(ocelot, port,
761 					       DEVLINK_PORT_FLAVOUR_PHYSICAL);
762 		if (err) {
763 			of_node_put(portnp);
764 			goto out_teardown;
765 		}
766 
767 		err = ocelot_probe_port(ocelot, port, target, portnp);
768 		if (err) {
769 			ocelot_port_devlink_teardown(ocelot, port);
770 			continue;
771 		}
772 
773 		devlink_ports_registered |= BIT(port);
774 
775 		ocelot_port = ocelot->ports[port];
776 		priv = container_of(ocelot_port, struct ocelot_port_private,
777 				    port);
778 		dlp = &ocelot->devlink_ports[port];
779 		devlink_port_type_eth_set(dlp, priv->dev);
780 	}
781 
782 	/* Initialize unused devlink ports at the end */
783 	for (port = 0; port < ocelot->num_phys_ports; port++) {
784 		if (devlink_ports_registered & BIT(port))
785 			continue;
786 
787 		err = ocelot_port_devlink_init(ocelot, port,
788 					       DEVLINK_PORT_FLAVOUR_UNUSED);
789 		if (err)
790 			goto out_teardown;
791 
792 		devlink_ports_registered |= BIT(port);
793 	}
794 
795 	return 0;
796 
797 out_teardown:
798 	/* Unregister the network interfaces */
799 	mscc_ocelot_release_ports(ocelot);
800 	/* Tear down devlink ports for the registered network interfaces */
801 	for (port = 0; port < ocelot->num_phys_ports; port++) {
802 		if (devlink_ports_registered & BIT(port))
803 			ocelot_port_devlink_teardown(ocelot, port);
804 	}
805 	return err;
806 }
807 
808 static int mscc_ocelot_probe(struct platform_device *pdev)
809 {
810 	struct device_node *np = pdev->dev.of_node;
811 	int err, irq_xtr, irq_ptp_rdy;
812 	struct device_node *ports;
813 	struct devlink *devlink;
814 	struct ocelot *ocelot;
815 	struct regmap *hsio;
816 	unsigned int i;
817 
818 	struct {
819 		enum ocelot_target id;
820 		char *name;
821 		u8 optional:1;
822 	} io_target[] = {
823 		{ SYS, "sys" },
824 		{ REW, "rew" },
825 		{ QSYS, "qsys" },
826 		{ ANA, "ana" },
827 		{ QS, "qs" },
828 		{ S0, "s0" },
829 		{ S1, "s1" },
830 		{ S2, "s2" },
831 		{ PTP, "ptp", 1 },
832 		{ FDMA, "fdma", 1 },
833 	};
834 
835 	if (!np && !pdev->dev.platform_data)
836 		return -ENODEV;
837 
838 	devlink =
839 		devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev);
840 	if (!devlink)
841 		return -ENOMEM;
842 
843 	ocelot = devlink_priv(devlink);
844 	ocelot->devlink = priv_to_devlink(ocelot);
845 	platform_set_drvdata(pdev, ocelot);
846 	ocelot->dev = &pdev->dev;
847 
848 	for (i = 0; i < ARRAY_SIZE(io_target); i++) {
849 		struct regmap *target;
850 		struct resource *res;
851 
852 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
853 						   io_target[i].name);
854 
855 		target = ocelot_regmap_init(ocelot, res);
856 		if (IS_ERR(target)) {
857 			if (io_target[i].optional) {
858 				ocelot->targets[io_target[i].id] = NULL;
859 				continue;
860 			}
861 			err = PTR_ERR(target);
862 			goto out_free_devlink;
863 		}
864 
865 		ocelot->targets[io_target[i].id] = target;
866 	}
867 
868 	if (ocelot->targets[FDMA])
869 		ocelot_fdma_init(pdev, ocelot);
870 
871 	hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
872 	if (IS_ERR(hsio)) {
873 		dev_err(&pdev->dev, "missing hsio syscon\n");
874 		err = PTR_ERR(hsio);
875 		goto out_free_devlink;
876 	}
877 
878 	ocelot->targets[HSIO] = hsio;
879 
880 	err = ocelot_chip_init(ocelot, &ocelot_ops);
881 	if (err)
882 		goto out_free_devlink;
883 
884 	irq_xtr = platform_get_irq_byname(pdev, "xtr");
885 	if (irq_xtr < 0) {
886 		err = irq_xtr;
887 		goto out_free_devlink;
888 	}
889 
890 	err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
891 					ocelot_xtr_irq_handler, IRQF_ONESHOT,
892 					"frame extraction", ocelot);
893 	if (err)
894 		goto out_free_devlink;
895 
896 	irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
897 	if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
898 		err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
899 						ocelot_ptp_rdy_irq_handler,
900 						IRQF_ONESHOT, "ptp ready",
901 						ocelot);
902 		if (err)
903 			goto out_free_devlink;
904 
905 		/* Both the PTP interrupt and the PTP bank are available */
906 		ocelot->ptp = 1;
907 	}
908 
909 	ports = of_get_child_by_name(np, "ethernet-ports");
910 	if (!ports) {
911 		dev_err(ocelot->dev, "no ethernet-ports child node found\n");
912 		err = -ENODEV;
913 		goto out_free_devlink;
914 	}
915 
916 	ocelot->num_phys_ports = of_get_child_count(ports);
917 	ocelot->num_flooding_pgids = 1;
918 
919 	ocelot->vcap = vsc7514_vcap_props;
920 
921 	ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE;
922 	ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX;
923 
924 	ocelot->npi = -1;
925 
926 	err = ocelot_init(ocelot);
927 	if (err)
928 		goto out_put_ports;
929 
930 	err = mscc_ocelot_init_ports(pdev, ports);
931 	if (err)
932 		goto out_ocelot_devlink_unregister;
933 
934 	if (ocelot->fdma)
935 		ocelot_fdma_start(ocelot);
936 
937 	err = ocelot_devlink_sb_register(ocelot);
938 	if (err)
939 		goto out_ocelot_release_ports;
940 
941 	if (ocelot->ptp) {
942 		err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
943 		if (err) {
944 			dev_err(ocelot->dev,
945 				"Timestamp initialization failed\n");
946 			ocelot->ptp = 0;
947 		}
948 	}
949 
950 	register_netdevice_notifier(&ocelot_netdevice_nb);
951 	register_switchdev_notifier(&ocelot_switchdev_nb);
952 	register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
953 
954 	of_node_put(ports);
955 	devlink_register(devlink);
956 
957 	dev_info(&pdev->dev, "Ocelot switch probed\n");
958 
959 	return 0;
960 
961 out_ocelot_release_ports:
962 	mscc_ocelot_release_ports(ocelot);
963 	mscc_ocelot_teardown_devlink_ports(ocelot);
964 out_ocelot_devlink_unregister:
965 	ocelot_deinit(ocelot);
966 out_put_ports:
967 	of_node_put(ports);
968 out_free_devlink:
969 	devlink_free(devlink);
970 	return err;
971 }
972 
973 static int mscc_ocelot_remove(struct platform_device *pdev)
974 {
975 	struct ocelot *ocelot = platform_get_drvdata(pdev);
976 
977 	if (ocelot->fdma)
978 		ocelot_fdma_deinit(ocelot);
979 	devlink_unregister(ocelot->devlink);
980 	ocelot_deinit_timestamp(ocelot);
981 	ocelot_devlink_sb_unregister(ocelot);
982 	mscc_ocelot_release_ports(ocelot);
983 	mscc_ocelot_teardown_devlink_ports(ocelot);
984 	ocelot_deinit(ocelot);
985 	unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
986 	unregister_switchdev_notifier(&ocelot_switchdev_nb);
987 	unregister_netdevice_notifier(&ocelot_netdevice_nb);
988 	devlink_free(ocelot->devlink);
989 
990 	return 0;
991 }
992 
993 static struct platform_driver mscc_ocelot_driver = {
994 	.probe = mscc_ocelot_probe,
995 	.remove = mscc_ocelot_remove,
996 	.driver = {
997 		.name = "ocelot-switch",
998 		.of_match_table = mscc_ocelot_match,
999 	},
1000 };
1001 
1002 module_platform_driver(mscc_ocelot_driver);
1003 
1004 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
1005 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
1006 MODULE_LICENSE("Dual MIT/GPL");
1007