1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Distributed Switch Architecture VSC9953 driver
3  * Copyright (C) 2020, Maxim Kochetkov <fido_max@inbox.ru>
4  */
5 #include <linux/types.h>
6 #include <soc/mscc/ocelot_vcap.h>
7 #include <soc/mscc/ocelot_sys.h>
8 #include <soc/mscc/ocelot.h>
9 #include <linux/mdio/mdio-mscc-miim.h>
10 #include <linux/of_mdio.h>
11 #include <linux/of_platform.h>
12 #include <linux/pcs-lynx.h>
13 #include <linux/dsa/ocelot.h>
14 #include <linux/iopoll.h>
15 #include "felix.h"
16 
17 #define VSC9953_NUM_PORTS			10
18 
19 #define VSC9953_VCAP_POLICER_BASE		11
20 #define VSC9953_VCAP_POLICER_MAX		31
21 #define VSC9953_VCAP_POLICER_BASE2		120
22 #define VSC9953_VCAP_POLICER_MAX2		161
23 
24 #define VSC9953_PORT_MODE_SERDES		(OCELOT_PORT_MODE_1000BASEX | \
25 						 OCELOT_PORT_MODE_SGMII | \
26 						 OCELOT_PORT_MODE_QSGMII)
27 
28 static const u32 vsc9953_port_modes[VSC9953_NUM_PORTS] = {
29 	VSC9953_PORT_MODE_SERDES,
30 	VSC9953_PORT_MODE_SERDES,
31 	VSC9953_PORT_MODE_SERDES,
32 	VSC9953_PORT_MODE_SERDES,
33 	VSC9953_PORT_MODE_SERDES,
34 	VSC9953_PORT_MODE_SERDES,
35 	VSC9953_PORT_MODE_SERDES,
36 	VSC9953_PORT_MODE_SERDES,
37 	OCELOT_PORT_MODE_INTERNAL,
38 	OCELOT_PORT_MODE_INTERNAL,
39 };
40 
41 static const u32 vsc9953_ana_regmap[] = {
42 	REG(ANA_ADVLEARN,			0x00b500),
43 	REG(ANA_VLANMASK,			0x00b504),
44 	REG_RESERVED(ANA_PORT_B_DOMAIN),
45 	REG(ANA_ANAGEFIL,			0x00b50c),
46 	REG(ANA_ANEVENTS,			0x00b510),
47 	REG(ANA_STORMLIMIT_BURST,		0x00b514),
48 	REG(ANA_STORMLIMIT_CFG,			0x00b518),
49 	REG(ANA_ISOLATED_PORTS,			0x00b528),
50 	REG(ANA_COMMUNITY_PORTS,		0x00b52c),
51 	REG(ANA_AUTOAGE,			0x00b530),
52 	REG(ANA_MACTOPTIONS,			0x00b534),
53 	REG(ANA_LEARNDISC,			0x00b538),
54 	REG(ANA_AGENCTRL,			0x00b53c),
55 	REG(ANA_MIRRORPORTS,			0x00b540),
56 	REG(ANA_EMIRRORPORTS,			0x00b544),
57 	REG(ANA_FLOODING,			0x00b548),
58 	REG(ANA_FLOODING_IPMC,			0x00b54c),
59 	REG(ANA_SFLOW_CFG,			0x00b550),
60 	REG(ANA_PORT_MODE,			0x00b57c),
61 	REG_RESERVED(ANA_CUT_THRU_CFG),
62 	REG(ANA_PGID_PGID,			0x00b600),
63 	REG(ANA_TABLES_ANMOVED,			0x00b4ac),
64 	REG(ANA_TABLES_MACHDATA,		0x00b4b0),
65 	REG(ANA_TABLES_MACLDATA,		0x00b4b4),
66 	REG_RESERVED(ANA_TABLES_STREAMDATA),
67 	REG(ANA_TABLES_MACACCESS,		0x00b4b8),
68 	REG(ANA_TABLES_MACTINDX,		0x00b4bc),
69 	REG(ANA_TABLES_VLANACCESS,		0x00b4c0),
70 	REG(ANA_TABLES_VLANTIDX,		0x00b4c4),
71 	REG_RESERVED(ANA_TABLES_ISDXACCESS),
72 	REG_RESERVED(ANA_TABLES_ISDXTIDX),
73 	REG(ANA_TABLES_ENTRYLIM,		0x00b480),
74 	REG_RESERVED(ANA_TABLES_PTP_ID_HIGH),
75 	REG_RESERVED(ANA_TABLES_PTP_ID_LOW),
76 	REG_RESERVED(ANA_TABLES_STREAMACCESS),
77 	REG_RESERVED(ANA_TABLES_STREAMTIDX),
78 	REG_RESERVED(ANA_TABLES_SEQ_HISTORY),
79 	REG_RESERVED(ANA_TABLES_SEQ_MASK),
80 	REG_RESERVED(ANA_TABLES_SFID_MASK),
81 	REG_RESERVED(ANA_TABLES_SFIDACCESS),
82 	REG_RESERVED(ANA_TABLES_SFIDTIDX),
83 	REG_RESERVED(ANA_MSTI_STATE),
84 	REG_RESERVED(ANA_OAM_UPM_LM_CNT),
85 	REG_RESERVED(ANA_SG_ACCESS_CTRL),
86 	REG_RESERVED(ANA_SG_CONFIG_REG_1),
87 	REG_RESERVED(ANA_SG_CONFIG_REG_2),
88 	REG_RESERVED(ANA_SG_CONFIG_REG_3),
89 	REG_RESERVED(ANA_SG_CONFIG_REG_4),
90 	REG_RESERVED(ANA_SG_CONFIG_REG_5),
91 	REG_RESERVED(ANA_SG_GCL_GS_CONFIG),
92 	REG_RESERVED(ANA_SG_GCL_TI_CONFIG),
93 	REG_RESERVED(ANA_SG_STATUS_REG_1),
94 	REG_RESERVED(ANA_SG_STATUS_REG_2),
95 	REG_RESERVED(ANA_SG_STATUS_REG_3),
96 	REG(ANA_PORT_VLAN_CFG,			0x000000),
97 	REG(ANA_PORT_DROP_CFG,			0x000004),
98 	REG(ANA_PORT_QOS_CFG,			0x000008),
99 	REG(ANA_PORT_VCAP_CFG,			0x00000c),
100 	REG(ANA_PORT_VCAP_S1_KEY_CFG,		0x000010),
101 	REG(ANA_PORT_VCAP_S2_CFG,		0x00001c),
102 	REG(ANA_PORT_PCP_DEI_MAP,		0x000020),
103 	REG(ANA_PORT_CPU_FWD_CFG,		0x000060),
104 	REG(ANA_PORT_CPU_FWD_BPDU_CFG,		0x000064),
105 	REG(ANA_PORT_CPU_FWD_GARP_CFG,		0x000068),
106 	REG(ANA_PORT_CPU_FWD_CCM_CFG,		0x00006c),
107 	REG(ANA_PORT_PORT_CFG,			0x000070),
108 	REG(ANA_PORT_POL_CFG,			0x000074),
109 	REG_RESERVED(ANA_PORT_PTP_CFG),
110 	REG_RESERVED(ANA_PORT_PTP_DLY1_CFG),
111 	REG_RESERVED(ANA_PORT_PTP_DLY2_CFG),
112 	REG_RESERVED(ANA_PORT_SFID_CFG),
113 	REG(ANA_PFC_PFC_CFG,			0x00c000),
114 	REG_RESERVED(ANA_PFC_PFC_TIMER),
115 	REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
116 	REG_RESERVED(ANA_IPT_IPT),
117 	REG_RESERVED(ANA_PPT_PPT),
118 	REG_RESERVED(ANA_FID_MAP_FID_MAP),
119 	REG(ANA_AGGR_CFG,			0x00c600),
120 	REG(ANA_CPUQ_CFG,			0x00c604),
121 	REG_RESERVED(ANA_CPUQ_CFG2),
122 	REG(ANA_CPUQ_8021_CFG,			0x00c60c),
123 	REG(ANA_DSCP_CFG,			0x00c64c),
124 	REG(ANA_DSCP_REWR_CFG,			0x00c74c),
125 	REG(ANA_VCAP_RNG_TYPE_CFG,		0x00c78c),
126 	REG(ANA_VCAP_RNG_VAL_CFG,		0x00c7ac),
127 	REG_RESERVED(ANA_VRAP_CFG),
128 	REG_RESERVED(ANA_VRAP_HDR_DATA),
129 	REG_RESERVED(ANA_VRAP_HDR_MASK),
130 	REG(ANA_DISCARD_CFG,			0x00c7d8),
131 	REG(ANA_FID_CFG,			0x00c7dc),
132 	REG(ANA_POL_PIR_CFG,			0x00a000),
133 	REG(ANA_POL_CIR_CFG,			0x00a004),
134 	REG(ANA_POL_MODE_CFG,			0x00a008),
135 	REG(ANA_POL_PIR_STATE,			0x00a00c),
136 	REG(ANA_POL_CIR_STATE,			0x00a010),
137 	REG_RESERVED(ANA_POL_STATE),
138 	REG(ANA_POL_FLOWC,			0x00c280),
139 	REG(ANA_POL_HYST,			0x00c2ec),
140 	REG_RESERVED(ANA_POL_MISC_CFG),
141 };
142 
143 static const u32 vsc9953_qs_regmap[] = {
144 	REG(QS_XTR_GRP_CFG,			0x000000),
145 	REG(QS_XTR_RD,				0x000008),
146 	REG(QS_XTR_FRM_PRUNING,			0x000010),
147 	REG(QS_XTR_FLUSH,			0x000018),
148 	REG(QS_XTR_DATA_PRESENT,		0x00001c),
149 	REG(QS_XTR_CFG,				0x000020),
150 	REG(QS_INJ_GRP_CFG,			0x000024),
151 	REG(QS_INJ_WR,				0x00002c),
152 	REG(QS_INJ_CTRL,			0x000034),
153 	REG(QS_INJ_STATUS,			0x00003c),
154 	REG(QS_INJ_ERR,				0x000040),
155 	REG_RESERVED(QS_INH_DBG),
156 };
157 
158 static const u32 vsc9953_vcap_regmap[] = {
159 	/* VCAP_CORE_CFG */
160 	REG(VCAP_CORE_UPDATE_CTRL,		0x000000),
161 	REG(VCAP_CORE_MV_CFG,			0x000004),
162 	/* VCAP_CORE_CACHE */
163 	REG(VCAP_CACHE_ENTRY_DAT,		0x000008),
164 	REG(VCAP_CACHE_MASK_DAT,		0x000108),
165 	REG(VCAP_CACHE_ACTION_DAT,		0x000208),
166 	REG(VCAP_CACHE_CNT_DAT,			0x000308),
167 	REG(VCAP_CACHE_TG_DAT,			0x000388),
168 	/* VCAP_CONST */
169 	REG(VCAP_CONST_VCAP_VER,		0x000398),
170 	REG(VCAP_CONST_ENTRY_WIDTH,		0x00039c),
171 	REG(VCAP_CONST_ENTRY_CNT,		0x0003a0),
172 	REG(VCAP_CONST_ENTRY_SWCNT,		0x0003a4),
173 	REG(VCAP_CONST_ENTRY_TG_WIDTH,		0x0003a8),
174 	REG(VCAP_CONST_ACTION_DEF_CNT,		0x0003ac),
175 	REG(VCAP_CONST_ACTION_WIDTH,		0x0003b0),
176 	REG(VCAP_CONST_CNT_WIDTH,		0x0003b4),
177 	REG_RESERVED(VCAP_CONST_CORE_CNT),
178 	REG_RESERVED(VCAP_CONST_IF_CNT),
179 };
180 
181 static const u32 vsc9953_qsys_regmap[] = {
182 	REG(QSYS_PORT_MODE,			0x003600),
183 	REG(QSYS_SWITCH_PORT_MODE,		0x003630),
184 	REG(QSYS_STAT_CNT_CFG,			0x00365c),
185 	REG(QSYS_EEE_CFG,			0x003660),
186 	REG(QSYS_EEE_THRES,			0x003688),
187 	REG(QSYS_IGR_NO_SHARING,		0x00368c),
188 	REG(QSYS_EGR_NO_SHARING,		0x003690),
189 	REG(QSYS_SW_STATUS,			0x003694),
190 	REG(QSYS_EXT_CPU_CFG,			0x0036c0),
191 	REG_RESERVED(QSYS_PAD_CFG),
192 	REG(QSYS_CPU_GROUP_MAP,			0x0036c8),
193 	REG_RESERVED(QSYS_QMAP),
194 	REG_RESERVED(QSYS_ISDX_SGRP),
195 	REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
196 	REG_RESERVED(QSYS_TFRM_MISC),
197 	REG_RESERVED(QSYS_TFRM_PORT_DLY),
198 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_1),
199 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_2),
200 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_3),
201 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_4),
202 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_5),
203 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_6),
204 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_7),
205 	REG_RESERVED(QSYS_TFRM_TIMER_CFG_8),
206 	REG(QSYS_RED_PROFILE,			0x003724),
207 	REG(QSYS_RES_QOS_MODE,			0x003764),
208 	REG(QSYS_RES_CFG,			0x004000),
209 	REG(QSYS_RES_STAT,			0x004004),
210 	REG(QSYS_EGR_DROP_MODE,			0x003768),
211 	REG(QSYS_EQ_CTRL,			0x00376c),
212 	REG_RESERVED(QSYS_EVENTS_CORE),
213 	REG_RESERVED(QSYS_QMAXSDU_CFG_0),
214 	REG_RESERVED(QSYS_QMAXSDU_CFG_1),
215 	REG_RESERVED(QSYS_QMAXSDU_CFG_2),
216 	REG_RESERVED(QSYS_QMAXSDU_CFG_3),
217 	REG_RESERVED(QSYS_QMAXSDU_CFG_4),
218 	REG_RESERVED(QSYS_QMAXSDU_CFG_5),
219 	REG_RESERVED(QSYS_QMAXSDU_CFG_6),
220 	REG_RESERVED(QSYS_QMAXSDU_CFG_7),
221 	REG_RESERVED(QSYS_PREEMPTION_CFG),
222 	REG(QSYS_CIR_CFG,			0x000000),
223 	REG_RESERVED(QSYS_EIR_CFG),
224 	REG(QSYS_SE_CFG,			0x000008),
225 	REG(QSYS_SE_DWRR_CFG,			0x00000c),
226 	REG_RESERVED(QSYS_SE_CONNECT),
227 	REG_RESERVED(QSYS_SE_DLB_SENSE),
228 	REG(QSYS_CIR_STATE,			0x000044),
229 	REG_RESERVED(QSYS_EIR_STATE),
230 	REG_RESERVED(QSYS_SE_STATE),
231 	REG(QSYS_HSCH_MISC_CFG,			0x003774),
232 	REG_RESERVED(QSYS_TAG_CONFIG),
233 	REG_RESERVED(QSYS_TAS_PARAM_CFG_CTRL),
234 	REG_RESERVED(QSYS_PORT_MAX_SDU),
235 	REG_RESERVED(QSYS_PARAM_CFG_REG_1),
236 	REG_RESERVED(QSYS_PARAM_CFG_REG_2),
237 	REG_RESERVED(QSYS_PARAM_CFG_REG_3),
238 	REG_RESERVED(QSYS_PARAM_CFG_REG_4),
239 	REG_RESERVED(QSYS_PARAM_CFG_REG_5),
240 	REG_RESERVED(QSYS_GCL_CFG_REG_1),
241 	REG_RESERVED(QSYS_GCL_CFG_REG_2),
242 	REG_RESERVED(QSYS_PARAM_STATUS_REG_1),
243 	REG_RESERVED(QSYS_PARAM_STATUS_REG_2),
244 	REG_RESERVED(QSYS_PARAM_STATUS_REG_3),
245 	REG_RESERVED(QSYS_PARAM_STATUS_REG_4),
246 	REG_RESERVED(QSYS_PARAM_STATUS_REG_5),
247 	REG_RESERVED(QSYS_PARAM_STATUS_REG_6),
248 	REG_RESERVED(QSYS_PARAM_STATUS_REG_7),
249 	REG_RESERVED(QSYS_PARAM_STATUS_REG_8),
250 	REG_RESERVED(QSYS_PARAM_STATUS_REG_9),
251 	REG_RESERVED(QSYS_GCL_STATUS_REG_1),
252 	REG_RESERVED(QSYS_GCL_STATUS_REG_2),
253 };
254 
255 static const u32 vsc9953_rew_regmap[] = {
256 	REG(REW_PORT_VLAN_CFG,			0x000000),
257 	REG(REW_TAG_CFG,			0x000004),
258 	REG(REW_PORT_CFG,			0x000008),
259 	REG(REW_DSCP_CFG,			0x00000c),
260 	REG(REW_PCP_DEI_QOS_MAP_CFG,		0x000010),
261 	REG_RESERVED(REW_PTP_CFG),
262 	REG_RESERVED(REW_PTP_DLY1_CFG),
263 	REG_RESERVED(REW_RED_TAG_CFG),
264 	REG(REW_DSCP_REMAP_DP1_CFG,		0x000610),
265 	REG(REW_DSCP_REMAP_CFG,			0x000710),
266 	REG_RESERVED(REW_STAT_CFG),
267 	REG_RESERVED(REW_REW_STICKY),
268 	REG_RESERVED(REW_PPT),
269 };
270 
271 static const u32 vsc9953_sys_regmap[] = {
272 	REG(SYS_COUNT_RX_OCTETS,		0x000000),
273 	REG(SYS_COUNT_RX_UNICAST,		0x000004),
274 	REG(SYS_COUNT_RX_MULTICAST,		0x000008),
275 	REG(SYS_COUNT_RX_BROADCAST,		0x00000c),
276 	REG(SYS_COUNT_RX_SHORTS,		0x000010),
277 	REG(SYS_COUNT_RX_FRAGMENTS,		0x000014),
278 	REG(SYS_COUNT_RX_JABBERS,		0x000018),
279 	REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,	0x00001c),
280 	REG(SYS_COUNT_RX_SYM_ERRS,		0x000020),
281 	REG(SYS_COUNT_RX_64,			0x000024),
282 	REG(SYS_COUNT_RX_65_127,		0x000028),
283 	REG(SYS_COUNT_RX_128_255,		0x00002c),
284 	REG(SYS_COUNT_RX_256_511,		0x000030),
285 	REG(SYS_COUNT_RX_512_1023,		0x000034),
286 	REG(SYS_COUNT_RX_1024_1526,		0x000038),
287 	REG(SYS_COUNT_RX_1527_MAX,		0x00003c),
288 	REG(SYS_COUNT_RX_PAUSE,			0x000040),
289 	REG(SYS_COUNT_RX_CONTROL,		0x000044),
290 	REG(SYS_COUNT_RX_LONGS,			0x000048),
291 	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,	0x00004c),
292 	REG(SYS_COUNT_RX_RED_PRIO_0,		0x000050),
293 	REG(SYS_COUNT_RX_RED_PRIO_1,		0x000054),
294 	REG(SYS_COUNT_RX_RED_PRIO_2,		0x000058),
295 	REG(SYS_COUNT_RX_RED_PRIO_3,		0x00005c),
296 	REG(SYS_COUNT_RX_RED_PRIO_4,		0x000060),
297 	REG(SYS_COUNT_RX_RED_PRIO_5,		0x000064),
298 	REG(SYS_COUNT_RX_RED_PRIO_6,		0x000068),
299 	REG(SYS_COUNT_RX_RED_PRIO_7,		0x00006c),
300 	REG(SYS_COUNT_RX_YELLOW_PRIO_0,		0x000070),
301 	REG(SYS_COUNT_RX_YELLOW_PRIO_1,		0x000074),
302 	REG(SYS_COUNT_RX_YELLOW_PRIO_2,		0x000078),
303 	REG(SYS_COUNT_RX_YELLOW_PRIO_3,		0x00007c),
304 	REG(SYS_COUNT_RX_YELLOW_PRIO_4,		0x000080),
305 	REG(SYS_COUNT_RX_YELLOW_PRIO_5,		0x000084),
306 	REG(SYS_COUNT_RX_YELLOW_PRIO_6,		0x000088),
307 	REG(SYS_COUNT_RX_YELLOW_PRIO_7,		0x00008c),
308 	REG(SYS_COUNT_RX_GREEN_PRIO_0,		0x000090),
309 	REG(SYS_COUNT_RX_GREEN_PRIO_1,		0x000094),
310 	REG(SYS_COUNT_RX_GREEN_PRIO_2,		0x000098),
311 	REG(SYS_COUNT_RX_GREEN_PRIO_3,		0x00009c),
312 	REG(SYS_COUNT_RX_GREEN_PRIO_4,		0x0000a0),
313 	REG(SYS_COUNT_RX_GREEN_PRIO_5,		0x0000a4),
314 	REG(SYS_COUNT_RX_GREEN_PRIO_6,		0x0000a8),
315 	REG(SYS_COUNT_RX_GREEN_PRIO_7,		0x0000ac),
316 	REG(SYS_COUNT_TX_OCTETS,		0x000100),
317 	REG(SYS_COUNT_TX_UNICAST,		0x000104),
318 	REG(SYS_COUNT_TX_MULTICAST,		0x000108),
319 	REG(SYS_COUNT_TX_BROADCAST,		0x00010c),
320 	REG(SYS_COUNT_TX_COLLISION,		0x000110),
321 	REG(SYS_COUNT_TX_DROPS,			0x000114),
322 	REG(SYS_COUNT_TX_PAUSE,			0x000118),
323 	REG(SYS_COUNT_TX_64,			0x00011c),
324 	REG(SYS_COUNT_TX_65_127,		0x000120),
325 	REG(SYS_COUNT_TX_128_255,		0x000124),
326 	REG(SYS_COUNT_TX_256_511,		0x000128),
327 	REG(SYS_COUNT_TX_512_1023,		0x00012c),
328 	REG(SYS_COUNT_TX_1024_1526,		0x000130),
329 	REG(SYS_COUNT_TX_1527_MAX,		0x000134),
330 	REG(SYS_COUNT_TX_YELLOW_PRIO_0,		0x000138),
331 	REG(SYS_COUNT_TX_YELLOW_PRIO_1,		0x00013c),
332 	REG(SYS_COUNT_TX_YELLOW_PRIO_2,		0x000140),
333 	REG(SYS_COUNT_TX_YELLOW_PRIO_3,		0x000144),
334 	REG(SYS_COUNT_TX_YELLOW_PRIO_4,		0x000148),
335 	REG(SYS_COUNT_TX_YELLOW_PRIO_5,		0x00014c),
336 	REG(SYS_COUNT_TX_YELLOW_PRIO_6,		0x000150),
337 	REG(SYS_COUNT_TX_YELLOW_PRIO_7,		0x000154),
338 	REG(SYS_COUNT_TX_GREEN_PRIO_0,		0x000158),
339 	REG(SYS_COUNT_TX_GREEN_PRIO_1,		0x00015c),
340 	REG(SYS_COUNT_TX_GREEN_PRIO_2,		0x000160),
341 	REG(SYS_COUNT_TX_GREEN_PRIO_3,		0x000164),
342 	REG(SYS_COUNT_TX_GREEN_PRIO_4,		0x000168),
343 	REG(SYS_COUNT_TX_GREEN_PRIO_5,		0x00016c),
344 	REG(SYS_COUNT_TX_GREEN_PRIO_6,		0x000170),
345 	REG(SYS_COUNT_TX_GREEN_PRIO_7,		0x000174),
346 	REG(SYS_COUNT_TX_AGING,			0x000178),
347 	REG(SYS_COUNT_DROP_LOCAL,		0x000200),
348 	REG(SYS_COUNT_DROP_TAIL,		0x000204),
349 	REG(SYS_COUNT_DROP_YELLOW_PRIO_0,	0x000208),
350 	REG(SYS_COUNT_DROP_YELLOW_PRIO_1,	0x00020c),
351 	REG(SYS_COUNT_DROP_YELLOW_PRIO_2,	0x000210),
352 	REG(SYS_COUNT_DROP_YELLOW_PRIO_3,	0x000214),
353 	REG(SYS_COUNT_DROP_YELLOW_PRIO_4,	0x000218),
354 	REG(SYS_COUNT_DROP_YELLOW_PRIO_5,	0x00021c),
355 	REG(SYS_COUNT_DROP_YELLOW_PRIO_6,	0x000220),
356 	REG(SYS_COUNT_DROP_YELLOW_PRIO_7,	0x000224),
357 	REG(SYS_COUNT_DROP_GREEN_PRIO_0,	0x000228),
358 	REG(SYS_COUNT_DROP_GREEN_PRIO_1,	0x00022c),
359 	REG(SYS_COUNT_DROP_GREEN_PRIO_2,	0x000230),
360 	REG(SYS_COUNT_DROP_GREEN_PRIO_3,	0x000234),
361 	REG(SYS_COUNT_DROP_GREEN_PRIO_4,	0x000238),
362 	REG(SYS_COUNT_DROP_GREEN_PRIO_5,	0x00023c),
363 	REG(SYS_COUNT_DROP_GREEN_PRIO_6,	0x000240),
364 	REG(SYS_COUNT_DROP_GREEN_PRIO_7,	0x000244),
365 	REG(SYS_RESET_CFG,			0x000318),
366 	REG_RESERVED(SYS_SR_ETYPE_CFG),
367 	REG(SYS_VLAN_ETYPE_CFG,			0x000320),
368 	REG(SYS_PORT_MODE,			0x000324),
369 	REG(SYS_FRONT_PORT_MODE,		0x000354),
370 	REG(SYS_FRM_AGING,			0x00037c),
371 	REG(SYS_STAT_CFG,			0x000380),
372 	REG_RESERVED(SYS_SW_STATUS),
373 	REG_RESERVED(SYS_MISC_CFG),
374 	REG_RESERVED(SYS_REW_MAC_HIGH_CFG),
375 	REG_RESERVED(SYS_REW_MAC_LOW_CFG),
376 	REG_RESERVED(SYS_TIMESTAMP_OFFSET),
377 	REG(SYS_PAUSE_CFG,			0x00044c),
378 	REG(SYS_PAUSE_TOT_CFG,			0x000478),
379 	REG(SYS_ATOP,				0x00047c),
380 	REG(SYS_ATOP_TOT_CFG,			0x0004a8),
381 	REG(SYS_MAC_FC_CFG,			0x0004ac),
382 	REG(SYS_MMGT,				0x0004d4),
383 	REG_RESERVED(SYS_MMGT_FAST),
384 	REG_RESERVED(SYS_EVENTS_DIF),
385 	REG_RESERVED(SYS_EVENTS_CORE),
386 	REG_RESERVED(SYS_CNT),
387 	REG_RESERVED(SYS_PTP_STATUS),
388 	REG_RESERVED(SYS_PTP_TXSTAMP),
389 	REG_RESERVED(SYS_PTP_NXT),
390 	REG_RESERVED(SYS_PTP_CFG),
391 	REG_RESERVED(SYS_RAM_INIT),
392 	REG_RESERVED(SYS_CM_ADDR),
393 	REG_RESERVED(SYS_CM_DATA_WR),
394 	REG_RESERVED(SYS_CM_DATA_RD),
395 	REG_RESERVED(SYS_CM_OP),
396 	REG_RESERVED(SYS_CM_DATA),
397 };
398 
399 static const u32 vsc9953_gcb_regmap[] = {
400 	REG(GCB_SOFT_RST,			0x000008),
401 	REG(GCB_MIIM_MII_STATUS,		0x0000ac),
402 	REG(GCB_MIIM_MII_CMD,			0x0000b4),
403 	REG(GCB_MIIM_MII_DATA,			0x0000b8),
404 };
405 
406 static const u32 vsc9953_dev_gmii_regmap[] = {
407 	REG(DEV_CLOCK_CFG,			0x0),
408 	REG(DEV_PORT_MISC,			0x4),
409 	REG_RESERVED(DEV_EVENTS),
410 	REG(DEV_EEE_CFG,			0xc),
411 	REG_RESERVED(DEV_RX_PATH_DELAY),
412 	REG_RESERVED(DEV_TX_PATH_DELAY),
413 	REG_RESERVED(DEV_PTP_PREDICT_CFG),
414 	REG(DEV_MAC_ENA_CFG,			0x10),
415 	REG(DEV_MAC_MODE_CFG,			0x14),
416 	REG(DEV_MAC_MAXLEN_CFG,			0x18),
417 	REG(DEV_MAC_TAGS_CFG,			0x1c),
418 	REG(DEV_MAC_ADV_CHK_CFG,		0x20),
419 	REG(DEV_MAC_IFG_CFG,			0x24),
420 	REG(DEV_MAC_HDX_CFG,			0x28),
421 	REG_RESERVED(DEV_MAC_DBG_CFG),
422 	REG(DEV_MAC_FC_MAC_LOW_CFG,		0x30),
423 	REG(DEV_MAC_FC_MAC_HIGH_CFG,		0x34),
424 	REG(DEV_MAC_STICKY,			0x38),
425 	REG_RESERVED(PCS1G_CFG),
426 	REG_RESERVED(PCS1G_MODE_CFG),
427 	REG_RESERVED(PCS1G_SD_CFG),
428 	REG_RESERVED(PCS1G_ANEG_CFG),
429 	REG_RESERVED(PCS1G_ANEG_NP_CFG),
430 	REG_RESERVED(PCS1G_LB_CFG),
431 	REG_RESERVED(PCS1G_DBG_CFG),
432 	REG_RESERVED(PCS1G_CDET_CFG),
433 	REG_RESERVED(PCS1G_ANEG_STATUS),
434 	REG_RESERVED(PCS1G_ANEG_NP_STATUS),
435 	REG_RESERVED(PCS1G_LINK_STATUS),
436 	REG_RESERVED(PCS1G_LINK_DOWN_CNT),
437 	REG_RESERVED(PCS1G_STICKY),
438 	REG_RESERVED(PCS1G_DEBUG_STATUS),
439 	REG_RESERVED(PCS1G_LPI_CFG),
440 	REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
441 	REG_RESERVED(PCS1G_LPI_STATUS),
442 	REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
443 	REG_RESERVED(PCS1G_TSTPAT_STATUS),
444 	REG_RESERVED(DEV_PCS_FX100_CFG),
445 	REG_RESERVED(DEV_PCS_FX100_STATUS),
446 };
447 
448 static const u32 *vsc9953_regmap[TARGET_MAX] = {
449 	[ANA]		= vsc9953_ana_regmap,
450 	[QS]		= vsc9953_qs_regmap,
451 	[QSYS]		= vsc9953_qsys_regmap,
452 	[REW]		= vsc9953_rew_regmap,
453 	[SYS]		= vsc9953_sys_regmap,
454 	[S0]		= vsc9953_vcap_regmap,
455 	[S1]		= vsc9953_vcap_regmap,
456 	[S2]		= vsc9953_vcap_regmap,
457 	[GCB]		= vsc9953_gcb_regmap,
458 	[DEV_GMII]	= vsc9953_dev_gmii_regmap,
459 };
460 
461 /* Addresses are relative to the device's base address */
462 static const struct resource vsc9953_target_io_res[TARGET_MAX] = {
463 	[ANA] = {
464 		.start	= 0x0280000,
465 		.end	= 0x028ffff,
466 		.name	= "ana",
467 	},
468 	[QS] = {
469 		.start	= 0x0080000,
470 		.end	= 0x00800ff,
471 		.name	= "qs",
472 	},
473 	[QSYS] = {
474 		.start	= 0x0200000,
475 		.end	= 0x021ffff,
476 		.name	= "qsys",
477 	},
478 	[REW] = {
479 		.start	= 0x0030000,
480 		.end	= 0x003ffff,
481 		.name	= "rew",
482 	},
483 	[SYS] = {
484 		.start	= 0x0010000,
485 		.end	= 0x001ffff,
486 		.name	= "sys",
487 	},
488 	[S0] = {
489 		.start	= 0x0040000,
490 		.end	= 0x00403ff,
491 		.name	= "s0",
492 	},
493 	[S1] = {
494 		.start	= 0x0050000,
495 		.end	= 0x00503ff,
496 		.name	= "s1",
497 	},
498 	[S2] = {
499 		.start	= 0x0060000,
500 		.end	= 0x00603ff,
501 		.name	= "s2",
502 	},
503 	[PTP] = {
504 		.start	= 0x0090000,
505 		.end	= 0x00900cb,
506 		.name	= "ptp",
507 	},
508 	[GCB] = {
509 		.start	= 0x0070000,
510 		.end	= 0x00701ff,
511 		.name	= "devcpu_gcb",
512 	},
513 };
514 
515 static const struct resource vsc9953_port_io_res[] = {
516 	{
517 		.start	= 0x0100000,
518 		.end	= 0x010ffff,
519 		.name	= "port0",
520 	},
521 	{
522 		.start	= 0x0110000,
523 		.end	= 0x011ffff,
524 		.name	= "port1",
525 	},
526 	{
527 		.start	= 0x0120000,
528 		.end	= 0x012ffff,
529 		.name	= "port2",
530 	},
531 	{
532 		.start	= 0x0130000,
533 		.end	= 0x013ffff,
534 		.name	= "port3",
535 	},
536 	{
537 		.start	= 0x0140000,
538 		.end	= 0x014ffff,
539 		.name	= "port4",
540 	},
541 	{
542 		.start	= 0x0150000,
543 		.end	= 0x015ffff,
544 		.name	= "port5",
545 	},
546 	{
547 		.start	= 0x0160000,
548 		.end	= 0x016ffff,
549 		.name	= "port6",
550 	},
551 	{
552 		.start	= 0x0170000,
553 		.end	= 0x017ffff,
554 		.name	= "port7",
555 	},
556 	{
557 		.start	= 0x0180000,
558 		.end	= 0x018ffff,
559 		.name	= "port8",
560 	},
561 	{
562 		.start	= 0x0190000,
563 		.end	= 0x019ffff,
564 		.name	= "port9",
565 	},
566 };
567 
568 static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
569 	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 10, 10),
570 	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 9),
571 	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
572 	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
573 	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
574 	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
575 	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
576 	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
577 	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
578 	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
579 	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
580 	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
581 	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
582 	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
583 	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
584 	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
585 	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
586 	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
587 	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
588 	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
589 	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
590 	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
591 	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
592 	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
593 	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
594 	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
595 	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
596 	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
597 	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 7, 7),
598 	[SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 6, 6),
599 	[SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 5, 5),
600 	[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
601 	[GCB_MIIM_MII_STATUS_PENDING] = REG_FIELD(GCB_MIIM_MII_STATUS, 2, 2),
602 	[GCB_MIIM_MII_STATUS_BUSY] = REG_FIELD(GCB_MIIM_MII_STATUS, 3, 3),
603 	/* Replicated per number of ports (11), register size 4 per port */
604 	[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 13, 13, 11, 4),
605 	[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 11, 4),
606 	[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 11, 4),
607 	[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 11, 4),
608 	[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 11, 4),
609 	[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 4, 5, 11, 4),
610 	[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 2, 3, 11, 4),
611 	[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 11, 4),
612 	[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 11, 20, 11, 4),
613 	[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 10, 11, 4),
614 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),
615 };
616 
617 static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = {
618 	[OCELOT_STAT_RX_OCTETS] = {
619 		.name = "rx_octets",
620 		.reg = SYS_COUNT_RX_OCTETS,
621 	},
622 	[OCELOT_STAT_RX_UNICAST] = {
623 		.name = "rx_unicast",
624 		.reg = SYS_COUNT_RX_UNICAST,
625 	},
626 	[OCELOT_STAT_RX_MULTICAST] = {
627 		.name = "rx_multicast",
628 		.reg = SYS_COUNT_RX_MULTICAST,
629 	},
630 	[OCELOT_STAT_RX_BROADCAST] = {
631 		.name = "rx_broadcast",
632 		.reg = SYS_COUNT_RX_BROADCAST,
633 	},
634 	[OCELOT_STAT_RX_SHORTS] = {
635 		.name = "rx_shorts",
636 		.reg = SYS_COUNT_RX_SHORTS,
637 	},
638 	[OCELOT_STAT_RX_FRAGMENTS] = {
639 		.name = "rx_fragments",
640 		.reg = SYS_COUNT_RX_FRAGMENTS,
641 	},
642 	[OCELOT_STAT_RX_JABBERS] = {
643 		.name = "rx_jabbers",
644 		.reg = SYS_COUNT_RX_JABBERS,
645 	},
646 	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
647 		.name = "rx_crc_align_errs",
648 		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
649 	},
650 	[OCELOT_STAT_RX_SYM_ERRS] = {
651 		.name = "rx_sym_errs",
652 		.reg = SYS_COUNT_RX_SYM_ERRS,
653 	},
654 	[OCELOT_STAT_RX_64] = {
655 		.name = "rx_frames_below_65_octets",
656 		.reg = SYS_COUNT_RX_64,
657 	},
658 	[OCELOT_STAT_RX_65_127] = {
659 		.name = "rx_frames_65_to_127_octets",
660 		.reg = SYS_COUNT_RX_65_127,
661 	},
662 	[OCELOT_STAT_RX_128_255] = {
663 		.name = "rx_frames_128_to_255_octets",
664 		.reg = SYS_COUNT_RX_128_255,
665 	},
666 	[OCELOT_STAT_RX_256_511] = {
667 		.name = "rx_frames_256_to_511_octets",
668 		.reg = SYS_COUNT_RX_256_511,
669 	},
670 	[OCELOT_STAT_RX_512_1023] = {
671 		.name = "rx_frames_512_to_1023_octets",
672 		.reg = SYS_COUNT_RX_512_1023,
673 	},
674 	[OCELOT_STAT_RX_1024_1526] = {
675 		.name = "rx_frames_1024_to_1526_octets",
676 		.reg = SYS_COUNT_RX_1024_1526,
677 	},
678 	[OCELOT_STAT_RX_1527_MAX] = {
679 		.name = "rx_frames_over_1526_octets",
680 		.reg = SYS_COUNT_RX_1527_MAX,
681 	},
682 	[OCELOT_STAT_RX_PAUSE] = {
683 		.name = "rx_pause",
684 		.reg = SYS_COUNT_RX_PAUSE,
685 	},
686 	[OCELOT_STAT_RX_CONTROL] = {
687 		.name = "rx_control",
688 		.reg = SYS_COUNT_RX_CONTROL,
689 	},
690 	[OCELOT_STAT_RX_LONGS] = {
691 		.name = "rx_longs",
692 		.reg = SYS_COUNT_RX_LONGS,
693 	},
694 	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
695 		.name = "rx_classified_drops",
696 		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
697 	},
698 	[OCELOT_STAT_RX_RED_PRIO_0] = {
699 		.name = "rx_red_prio_0",
700 		.reg = SYS_COUNT_RX_RED_PRIO_0,
701 	},
702 	[OCELOT_STAT_RX_RED_PRIO_1] = {
703 		.name = "rx_red_prio_1",
704 		.reg = SYS_COUNT_RX_RED_PRIO_1,
705 	},
706 	[OCELOT_STAT_RX_RED_PRIO_2] = {
707 		.name = "rx_red_prio_2",
708 		.reg = SYS_COUNT_RX_RED_PRIO_2,
709 	},
710 	[OCELOT_STAT_RX_RED_PRIO_3] = {
711 		.name = "rx_red_prio_3",
712 		.reg = SYS_COUNT_RX_RED_PRIO_3,
713 	},
714 	[OCELOT_STAT_RX_RED_PRIO_4] = {
715 		.name = "rx_red_prio_4",
716 		.reg = SYS_COUNT_RX_RED_PRIO_4,
717 	},
718 	[OCELOT_STAT_RX_RED_PRIO_5] = {
719 		.name = "rx_red_prio_5",
720 		.reg = SYS_COUNT_RX_RED_PRIO_5,
721 	},
722 	[OCELOT_STAT_RX_RED_PRIO_6] = {
723 		.name = "rx_red_prio_6",
724 		.reg = SYS_COUNT_RX_RED_PRIO_6,
725 	},
726 	[OCELOT_STAT_RX_RED_PRIO_7] = {
727 		.name = "rx_red_prio_7",
728 		.reg = SYS_COUNT_RX_RED_PRIO_7,
729 	},
730 	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
731 		.name = "rx_yellow_prio_0",
732 		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
733 	},
734 	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
735 		.name = "rx_yellow_prio_1",
736 		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
737 	},
738 	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
739 		.name = "rx_yellow_prio_2",
740 		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
741 	},
742 	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
743 		.name = "rx_yellow_prio_3",
744 		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
745 	},
746 	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
747 		.name = "rx_yellow_prio_4",
748 		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
749 	},
750 	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
751 		.name = "rx_yellow_prio_5",
752 		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
753 	},
754 	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
755 		.name = "rx_yellow_prio_6",
756 		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
757 	},
758 	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
759 		.name = "rx_yellow_prio_7",
760 		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
761 	},
762 	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
763 		.name = "rx_green_prio_0",
764 		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
765 	},
766 	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
767 		.name = "rx_green_prio_1",
768 		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
769 	},
770 	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
771 		.name = "rx_green_prio_2",
772 		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
773 	},
774 	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
775 		.name = "rx_green_prio_3",
776 		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
777 	},
778 	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
779 		.name = "rx_green_prio_4",
780 		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
781 	},
782 	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
783 		.name = "rx_green_prio_5",
784 		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
785 	},
786 	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
787 		.name = "rx_green_prio_6",
788 		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
789 	},
790 	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
791 		.name = "rx_green_prio_7",
792 		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
793 	},
794 	[OCELOT_STAT_TX_OCTETS] = {
795 		.name = "tx_octets",
796 		.reg = SYS_COUNT_TX_OCTETS,
797 	},
798 	[OCELOT_STAT_TX_UNICAST] = {
799 		.name = "tx_unicast",
800 		.reg = SYS_COUNT_TX_UNICAST,
801 	},
802 	[OCELOT_STAT_TX_MULTICAST] = {
803 		.name = "tx_multicast",
804 		.reg = SYS_COUNT_TX_MULTICAST,
805 	},
806 	[OCELOT_STAT_TX_BROADCAST] = {
807 		.name = "tx_broadcast",
808 		.reg = SYS_COUNT_TX_BROADCAST,
809 	},
810 	[OCELOT_STAT_TX_COLLISION] = {
811 		.name = "tx_collision",
812 		.reg = SYS_COUNT_TX_COLLISION,
813 	},
814 	[OCELOT_STAT_TX_DROPS] = {
815 		.name = "tx_drops",
816 		.reg = SYS_COUNT_TX_DROPS,
817 	},
818 	[OCELOT_STAT_TX_PAUSE] = {
819 		.name = "tx_pause",
820 		.reg = SYS_COUNT_TX_PAUSE,
821 	},
822 	[OCELOT_STAT_TX_64] = {
823 		.name = "tx_frames_below_65_octets",
824 		.reg = SYS_COUNT_TX_64,
825 	},
826 	[OCELOT_STAT_TX_65_127] = {
827 		.name = "tx_frames_65_to_127_octets",
828 		.reg = SYS_COUNT_TX_65_127,
829 	},
830 	[OCELOT_STAT_TX_128_255] = {
831 		.name = "tx_frames_128_255_octets",
832 		.reg = SYS_COUNT_TX_128_255,
833 	},
834 	[OCELOT_STAT_TX_256_511] = {
835 		.name = "tx_frames_256_511_octets",
836 		.reg = SYS_COUNT_TX_256_511,
837 	},
838 	[OCELOT_STAT_TX_512_1023] = {
839 		.name = "tx_frames_512_1023_octets",
840 		.reg = SYS_COUNT_TX_512_1023,
841 	},
842 	[OCELOT_STAT_TX_1024_1526] = {
843 		.name = "tx_frames_1024_1526_octets",
844 		.reg = SYS_COUNT_TX_1024_1526,
845 	},
846 	[OCELOT_STAT_TX_1527_MAX] = {
847 		.name = "tx_frames_over_1526_octets",
848 		.reg = SYS_COUNT_TX_1527_MAX,
849 	},
850 	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
851 		.name = "tx_yellow_prio_0",
852 		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
853 	},
854 	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
855 		.name = "tx_yellow_prio_1",
856 		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
857 	},
858 	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
859 		.name = "tx_yellow_prio_2",
860 		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
861 	},
862 	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
863 		.name = "tx_yellow_prio_3",
864 		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
865 	},
866 	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
867 		.name = "tx_yellow_prio_4",
868 		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
869 	},
870 	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
871 		.name = "tx_yellow_prio_5",
872 		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
873 	},
874 	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
875 		.name = "tx_yellow_prio_6",
876 		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
877 	},
878 	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
879 		.name = "tx_yellow_prio_7",
880 		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
881 	},
882 	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
883 		.name = "tx_green_prio_0",
884 		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
885 	},
886 	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
887 		.name = "tx_green_prio_1",
888 		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
889 	},
890 	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
891 		.name = "tx_green_prio_2",
892 		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
893 	},
894 	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
895 		.name = "tx_green_prio_3",
896 		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
897 	},
898 	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
899 		.name = "tx_green_prio_4",
900 		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
901 	},
902 	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
903 		.name = "tx_green_prio_5",
904 		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
905 	},
906 	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
907 		.name = "tx_green_prio_6",
908 		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
909 	},
910 	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
911 		.name = "tx_green_prio_7",
912 		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
913 	},
914 	[OCELOT_STAT_TX_AGED] = {
915 		.name = "tx_aged",
916 		.reg = SYS_COUNT_TX_AGING,
917 	},
918 	[OCELOT_STAT_DROP_LOCAL] = {
919 		.name = "drop_local",
920 		.reg = SYS_COUNT_DROP_LOCAL,
921 	},
922 	[OCELOT_STAT_DROP_TAIL] = {
923 		.name = "drop_tail",
924 		.reg = SYS_COUNT_DROP_TAIL,
925 	},
926 	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
927 		.name = "drop_yellow_prio_0",
928 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
929 	},
930 	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
931 		.name = "drop_yellow_prio_1",
932 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
933 	},
934 	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
935 		.name = "drop_yellow_prio_2",
936 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
937 	},
938 	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
939 		.name = "drop_yellow_prio_3",
940 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
941 	},
942 	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
943 		.name = "drop_yellow_prio_4",
944 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
945 	},
946 	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
947 		.name = "drop_yellow_prio_5",
948 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
949 	},
950 	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
951 		.name = "drop_yellow_prio_6",
952 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
953 	},
954 	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
955 		.name = "drop_yellow_prio_7",
956 		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
957 	},
958 	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
959 		.name = "drop_green_prio_0",
960 		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
961 	},
962 	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
963 		.name = "drop_green_prio_1",
964 		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
965 	},
966 	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
967 		.name = "drop_green_prio_2",
968 		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
969 	},
970 	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
971 		.name = "drop_green_prio_3",
972 		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
973 	},
974 	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
975 		.name = "drop_green_prio_4",
976 		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
977 	},
978 	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
979 		.name = "drop_green_prio_5",
980 		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
981 	},
982 	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
983 		.name = "drop_green_prio_6",
984 		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
985 	},
986 	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
987 		.name = "drop_green_prio_7",
988 		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
989 	},
990 };
991 
992 static const struct vcap_field vsc9953_vcap_es0_keys[] = {
993 	[VCAP_ES0_EGR_PORT]			= {  0,  4},
994 	[VCAP_ES0_IGR_PORT]			= {  4,  4},
995 	[VCAP_ES0_RSV]				= {  8,  2},
996 	[VCAP_ES0_L2_MC]			= { 10,  1},
997 	[VCAP_ES0_L2_BC]			= { 11,  1},
998 	[VCAP_ES0_VID]				= { 12, 12},
999 	[VCAP_ES0_DP]				= { 24,  1},
1000 	[VCAP_ES0_PCP]				= { 25,  3},
1001 };
1002 
1003 static const struct vcap_field vsc9953_vcap_es0_actions[] = {
1004 	[VCAP_ES0_ACT_PUSH_OUTER_TAG]		= {  0,  2},
1005 	[VCAP_ES0_ACT_PUSH_INNER_TAG]		= {  2,  1},
1006 	[VCAP_ES0_ACT_TAG_A_TPID_SEL]		= {  3,  2},
1007 	[VCAP_ES0_ACT_TAG_A_VID_SEL]		= {  5,  1},
1008 	[VCAP_ES0_ACT_TAG_A_PCP_SEL]		= {  6,  2},
1009 	[VCAP_ES0_ACT_TAG_A_DEI_SEL]		= {  8,  2},
1010 	[VCAP_ES0_ACT_TAG_B_TPID_SEL]		= { 10,  2},
1011 	[VCAP_ES0_ACT_TAG_B_VID_SEL]		= { 12,  1},
1012 	[VCAP_ES0_ACT_TAG_B_PCP_SEL]		= { 13,  2},
1013 	[VCAP_ES0_ACT_TAG_B_DEI_SEL]		= { 15,  2},
1014 	[VCAP_ES0_ACT_VID_A_VAL]		= { 17, 12},
1015 	[VCAP_ES0_ACT_PCP_A_VAL]		= { 29,  3},
1016 	[VCAP_ES0_ACT_DEI_A_VAL]		= { 32,  1},
1017 	[VCAP_ES0_ACT_VID_B_VAL]		= { 33, 12},
1018 	[VCAP_ES0_ACT_PCP_B_VAL]		= { 45,  3},
1019 	[VCAP_ES0_ACT_DEI_B_VAL]		= { 48,  1},
1020 	[VCAP_ES0_ACT_RSV]			= { 49, 24},
1021 	[VCAP_ES0_ACT_HIT_STICKY]		= { 73,  1},
1022 };
1023 
1024 static const struct vcap_field vsc9953_vcap_is1_keys[] = {
1025 	[VCAP_IS1_HK_TYPE]			= {  0,   1},
1026 	[VCAP_IS1_HK_LOOKUP]			= {  1,   2},
1027 	[VCAP_IS1_HK_IGR_PORT_MASK]		= {  3,  11},
1028 	[VCAP_IS1_HK_RSV]			= { 14,  10},
1029 	/* VCAP_IS1_HK_OAM_Y1731 not supported */
1030 	[VCAP_IS1_HK_L2_MC]			= { 24,   1},
1031 	[VCAP_IS1_HK_L2_BC]			= { 25,   1},
1032 	[VCAP_IS1_HK_IP_MC]			= { 26,   1},
1033 	[VCAP_IS1_HK_VLAN_TAGGED]		= { 27,   1},
1034 	[VCAP_IS1_HK_VLAN_DBL_TAGGED]		= { 28,   1},
1035 	[VCAP_IS1_HK_TPID]			= { 29,   1},
1036 	[VCAP_IS1_HK_VID]			= { 30,  12},
1037 	[VCAP_IS1_HK_DEI]			= { 42,   1},
1038 	[VCAP_IS1_HK_PCP]			= { 43,   3},
1039 	/* Specific Fields for IS1 Half Key S1_NORMAL */
1040 	[VCAP_IS1_HK_L2_SMAC]			= { 46,  48},
1041 	[VCAP_IS1_HK_ETYPE_LEN]			= { 94,   1},
1042 	[VCAP_IS1_HK_ETYPE]			= { 95,  16},
1043 	[VCAP_IS1_HK_IP_SNAP]			= {111,   1},
1044 	[VCAP_IS1_HK_IP4]			= {112,   1},
1045 	/* Layer-3 Information */
1046 	[VCAP_IS1_HK_L3_FRAGMENT]		= {113,   1},
1047 	[VCAP_IS1_HK_L3_FRAG_OFS_GT0]		= {114,   1},
1048 	[VCAP_IS1_HK_L3_OPTIONS]		= {115,   1},
1049 	[VCAP_IS1_HK_L3_DSCP]			= {116,   6},
1050 	[VCAP_IS1_HK_L3_IP4_SIP]		= {122,  32},
1051 	/* Layer-4 Information */
1052 	[VCAP_IS1_HK_TCP_UDP]			= {154,   1},
1053 	[VCAP_IS1_HK_TCP]			= {155,   1},
1054 	[VCAP_IS1_HK_L4_SPORT]			= {156,  16},
1055 	[VCAP_IS1_HK_L4_RNG]			= {172,   8},
1056 	/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
1057 	[VCAP_IS1_HK_IP4_INNER_TPID]            = { 46,   1},
1058 	[VCAP_IS1_HK_IP4_INNER_VID]		= { 47,  12},
1059 	[VCAP_IS1_HK_IP4_INNER_DEI]		= { 59,   1},
1060 	[VCAP_IS1_HK_IP4_INNER_PCP]		= { 60,   3},
1061 	[VCAP_IS1_HK_IP4_IP4]			= { 63,   1},
1062 	[VCAP_IS1_HK_IP4_L3_FRAGMENT]		= { 64,   1},
1063 	[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0]	= { 65,   1},
1064 	[VCAP_IS1_HK_IP4_L3_OPTIONS]		= { 66,   1},
1065 	[VCAP_IS1_HK_IP4_L3_DSCP]		= { 67,   6},
1066 	[VCAP_IS1_HK_IP4_L3_IP4_DIP]		= { 73,  32},
1067 	[VCAP_IS1_HK_IP4_L3_IP4_SIP]		= {105,  32},
1068 	[VCAP_IS1_HK_IP4_L3_PROTO]		= {137,   8},
1069 	[VCAP_IS1_HK_IP4_TCP_UDP]		= {145,   1},
1070 	[VCAP_IS1_HK_IP4_TCP]			= {146,   1},
1071 	[VCAP_IS1_HK_IP4_L4_RNG]		= {147,   8},
1072 	[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE]	= {155,  32},
1073 };
1074 
1075 static const struct vcap_field vsc9953_vcap_is1_actions[] = {
1076 	[VCAP_IS1_ACT_DSCP_ENA]			= {  0,  1},
1077 	[VCAP_IS1_ACT_DSCP_VAL]			= {  1,  6},
1078 	[VCAP_IS1_ACT_QOS_ENA]			= {  7,  1},
1079 	[VCAP_IS1_ACT_QOS_VAL]			= {  8,  3},
1080 	[VCAP_IS1_ACT_DP_ENA]			= { 11,  1},
1081 	[VCAP_IS1_ACT_DP_VAL]			= { 12,  1},
1082 	[VCAP_IS1_ACT_PAG_OVERRIDE_MASK]	= { 13,  8},
1083 	[VCAP_IS1_ACT_PAG_VAL]			= { 21,  8},
1084 	[VCAP_IS1_ACT_RSV]			= { 29, 11},
1085 	[VCAP_IS1_ACT_VID_REPLACE_ENA]		= { 40,  1},
1086 	[VCAP_IS1_ACT_VID_ADD_VAL]		= { 41, 12},
1087 	[VCAP_IS1_ACT_FID_SEL]			= { 53,  2},
1088 	[VCAP_IS1_ACT_FID_VAL]			= { 55, 13},
1089 	[VCAP_IS1_ACT_PCP_DEI_ENA]		= { 68,  1},
1090 	[VCAP_IS1_ACT_PCP_VAL]			= { 69,  3},
1091 	[VCAP_IS1_ACT_DEI_VAL]			= { 72,  1},
1092 	[VCAP_IS1_ACT_VLAN_POP_CNT_ENA]		= { 73,  1},
1093 	[VCAP_IS1_ACT_VLAN_POP_CNT]		= { 74,  2},
1094 	[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA]	= { 76,  4},
1095 	[VCAP_IS1_ACT_HIT_STICKY]		= { 80,  1},
1096 };
1097 
1098 static struct vcap_field vsc9953_vcap_is2_keys[] = {
1099 	/* Common: 41 bits */
1100 	[VCAP_IS2_TYPE]				= {  0,   4},
1101 	[VCAP_IS2_HK_FIRST]			= {  4,   1},
1102 	[VCAP_IS2_HK_PAG]			= {  5,   8},
1103 	[VCAP_IS2_HK_IGR_PORT_MASK]		= { 13,  11},
1104 	[VCAP_IS2_HK_RSV2]			= { 24,   1},
1105 	[VCAP_IS2_HK_HOST_MATCH]		= { 25,   1},
1106 	[VCAP_IS2_HK_L2_MC]			= { 26,   1},
1107 	[VCAP_IS2_HK_L2_BC]			= { 27,   1},
1108 	[VCAP_IS2_HK_VLAN_TAGGED]		= { 28,   1},
1109 	[VCAP_IS2_HK_VID]			= { 29,  12},
1110 	[VCAP_IS2_HK_DEI]			= { 41,   1},
1111 	[VCAP_IS2_HK_PCP]			= { 42,   3},
1112 	/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
1113 	[VCAP_IS2_HK_L2_DMAC]			= { 45,  48},
1114 	[VCAP_IS2_HK_L2_SMAC]			= { 93,  48},
1115 	/* MAC_ETYPE (TYPE=000) */
1116 	[VCAP_IS2_HK_MAC_ETYPE_ETYPE]		= {141,  16},
1117 	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]	= {157,  16},
1118 	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]	= {173,   8},
1119 	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]	= {181,   3},
1120 	/* MAC_LLC (TYPE=001) */
1121 	[VCAP_IS2_HK_MAC_LLC_L2_LLC]		= {141,  40},
1122 	/* MAC_SNAP (TYPE=010) */
1123 	[VCAP_IS2_HK_MAC_SNAP_L2_SNAP]		= {141,  40},
1124 	/* MAC_ARP (TYPE=011) */
1125 	[VCAP_IS2_HK_MAC_ARP_SMAC]		= { 45,  48},
1126 	[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]	= { 93,   1},
1127 	[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]	= { 94,   1},
1128 	[VCAP_IS2_HK_MAC_ARP_LEN_OK]		= { 95,   1},
1129 	[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]	= { 96,   1},
1130 	[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]	= { 97,   1},
1131 	[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]	= { 98,   1},
1132 	[VCAP_IS2_HK_MAC_ARP_OPCODE]		= { 99,   2},
1133 	[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]	= {101,  32},
1134 	[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]	= {133,  32},
1135 	[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]	= {165,   1},
1136 	/* IP4_TCP_UDP / IP4_OTHER common */
1137 	[VCAP_IS2_HK_IP4]			= { 45,   1},
1138 	[VCAP_IS2_HK_L3_FRAGMENT]		= { 46,   1},
1139 	[VCAP_IS2_HK_L3_FRAG_OFS_GT0]		= { 47,   1},
1140 	[VCAP_IS2_HK_L3_OPTIONS]		= { 48,   1},
1141 	[VCAP_IS2_HK_IP4_L3_TTL_GT0]		= { 49,   1},
1142 	[VCAP_IS2_HK_L3_TOS]			= { 50,   8},
1143 	[VCAP_IS2_HK_L3_IP4_DIP]		= { 58,  32},
1144 	[VCAP_IS2_HK_L3_IP4_SIP]		= { 90,  32},
1145 	[VCAP_IS2_HK_DIP_EQ_SIP]		= {122,   1},
1146 	/* IP4_TCP_UDP (TYPE=100) */
1147 	[VCAP_IS2_HK_TCP]			= {123,   1},
1148 	[VCAP_IS2_HK_L4_DPORT]			= {124,  16},
1149 	[VCAP_IS2_HK_L4_SPORT]			= {140,  16},
1150 	[VCAP_IS2_HK_L4_RNG]			= {156,   8},
1151 	[VCAP_IS2_HK_L4_SPORT_EQ_DPORT]		= {164,   1},
1152 	[VCAP_IS2_HK_L4_SEQUENCE_EQ0]		= {165,   1},
1153 	[VCAP_IS2_HK_L4_FIN]			= {166,   1},
1154 	[VCAP_IS2_HK_L4_SYN]			= {167,   1},
1155 	[VCAP_IS2_HK_L4_RST]			= {168,   1},
1156 	[VCAP_IS2_HK_L4_PSH]			= {169,   1},
1157 	[VCAP_IS2_HK_L4_ACK]			= {170,   1},
1158 	[VCAP_IS2_HK_L4_URG]			= {171,   1},
1159 	/* IP4_OTHER (TYPE=101) */
1160 	[VCAP_IS2_HK_IP4_L3_PROTO]		= {123,   8},
1161 	[VCAP_IS2_HK_L3_PAYLOAD]		= {131,  56},
1162 	/* IP6_STD (TYPE=110) */
1163 	[VCAP_IS2_HK_IP6_L3_TTL_GT0]		= { 45,   1},
1164 	[VCAP_IS2_HK_L3_IP6_SIP]		= { 46, 128},
1165 	[VCAP_IS2_HK_IP6_L3_PROTO]		= {174,   8},
1166 };
1167 
1168 static struct vcap_field vsc9953_vcap_is2_actions[] = {
1169 	[VCAP_IS2_ACT_HIT_ME_ONCE]		= {  0,  1},
1170 	[VCAP_IS2_ACT_CPU_COPY_ENA]		= {  1,  1},
1171 	[VCAP_IS2_ACT_CPU_QU_NUM]		= {  2,  3},
1172 	[VCAP_IS2_ACT_MASK_MODE]		= {  5,  2},
1173 	[VCAP_IS2_ACT_MIRROR_ENA]		= {  7,  1},
1174 	[VCAP_IS2_ACT_LRN_DIS]			= {  8,  1},
1175 	[VCAP_IS2_ACT_POLICE_ENA]		= {  9,  1},
1176 	[VCAP_IS2_ACT_POLICE_IDX]		= { 10,  8},
1177 	[VCAP_IS2_ACT_POLICE_VCAP_ONLY]		= { 21,  1},
1178 	[VCAP_IS2_ACT_PORT_MASK]		= { 22, 10},
1179 	[VCAP_IS2_ACT_ACL_ID]			= { 44,  6},
1180 	[VCAP_IS2_ACT_HIT_CNT]			= { 50, 32},
1181 };
1182 
1183 static struct vcap_props vsc9953_vcap_props[] = {
1184 	[VCAP_ES0] = {
1185 		.action_type_width = 0,
1186 		.action_table = {
1187 			[ES0_ACTION_TYPE_NORMAL] = {
1188 				.width = 73, /* HIT_STICKY not included */
1189 				.count = 1,
1190 			},
1191 		},
1192 		.target = S0,
1193 		.keys = vsc9953_vcap_es0_keys,
1194 		.actions = vsc9953_vcap_es0_actions,
1195 	},
1196 	[VCAP_IS1] = {
1197 		.action_type_width = 0,
1198 		.action_table = {
1199 			[IS1_ACTION_TYPE_NORMAL] = {
1200 				.width = 80, /* HIT_STICKY not included */
1201 				.count = 4,
1202 			},
1203 		},
1204 		.target = S1,
1205 		.keys = vsc9953_vcap_is1_keys,
1206 		.actions = vsc9953_vcap_is1_actions,
1207 	},
1208 	[VCAP_IS2] = {
1209 		.action_type_width = 1,
1210 		.action_table = {
1211 			[IS2_ACTION_TYPE_NORMAL] = {
1212 				.width = 50, /* HIT_CNT not included */
1213 				.count = 2
1214 			},
1215 			[IS2_ACTION_TYPE_SMAC_SIP] = {
1216 				.width = 6,
1217 				.count = 4
1218 			},
1219 		},
1220 		.target = S2,
1221 		.keys = vsc9953_vcap_is2_keys,
1222 		.actions = vsc9953_vcap_is2_actions,
1223 	},
1224 };
1225 
1226 #define VSC9953_INIT_TIMEOUT			50000
1227 #define VSC9953_GCB_RST_SLEEP			100
1228 #define VSC9953_SYS_RAMINIT_SLEEP		80
1229 
1230 static int vsc9953_gcb_soft_rst_status(struct ocelot *ocelot)
1231 {
1232 	int val;
1233 
1234 	ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val);
1235 
1236 	return val;
1237 }
1238 
1239 static int vsc9953_sys_ram_init_status(struct ocelot *ocelot)
1240 {
1241 	int val;
1242 
1243 	ocelot_field_read(ocelot, SYS_RESET_CFG_MEM_INIT, &val);
1244 
1245 	return val;
1246 }
1247 
1248 
1249 /* CORE_ENA is in SYS:SYSTEM:RESET_CFG
1250  * MEM_INIT is in SYS:SYSTEM:RESET_CFG
1251  * MEM_ENA is in SYS:SYSTEM:RESET_CFG
1252  */
1253 static int vsc9953_reset(struct ocelot *ocelot)
1254 {
1255 	int val, err;
1256 
1257 	/* soft-reset the switch core */
1258 	ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1);
1259 
1260 	err = readx_poll_timeout(vsc9953_gcb_soft_rst_status, ocelot, val, !val,
1261 				 VSC9953_GCB_RST_SLEEP, VSC9953_INIT_TIMEOUT);
1262 	if (err) {
1263 		dev_err(ocelot->dev, "timeout: switch core reset\n");
1264 		return err;
1265 	}
1266 
1267 	/* initialize switch mem ~40us */
1268 	ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1);
1269 	ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_INIT, 1);
1270 
1271 	err = readx_poll_timeout(vsc9953_sys_ram_init_status, ocelot, val, !val,
1272 				 VSC9953_SYS_RAMINIT_SLEEP,
1273 				 VSC9953_INIT_TIMEOUT);
1274 	if (err) {
1275 		dev_err(ocelot->dev, "timeout: switch sram init\n");
1276 		return err;
1277 	}
1278 
1279 	/* enable switch core */
1280 	ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1);
1281 
1282 	return 0;
1283 }
1284 
1285 static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
1286 				     unsigned long *supported,
1287 				     struct phylink_link_state *state)
1288 {
1289 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
1290 
1291 	phylink_set_port_modes(mask);
1292 	phylink_set(mask, Autoneg);
1293 	phylink_set(mask, Pause);
1294 	phylink_set(mask, Asym_Pause);
1295 	phylink_set(mask, 10baseT_Full);
1296 	phylink_set(mask, 10baseT_Half);
1297 	phylink_set(mask, 100baseT_Full);
1298 	phylink_set(mask, 100baseT_Half);
1299 	phylink_set(mask, 1000baseT_Full);
1300 	phylink_set(mask, 1000baseX_Full);
1301 
1302 	if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
1303 		phylink_set(mask, 2500baseT_Full);
1304 		phylink_set(mask, 2500baseX_Full);
1305 	}
1306 
1307 	linkmode_and(supported, supported, mask);
1308 	linkmode_and(state->advertising, state->advertising, mask);
1309 }
1310 
1311 /* Watermark encode
1312  * Bit 9:   Unit; 0:1, 1:16
1313  * Bit 8-0: Value to be multiplied with unit
1314  */
1315 static u16 vsc9953_wm_enc(u16 value)
1316 {
1317 	WARN_ON(value >= 16 * BIT(9));
1318 
1319 	if (value >= BIT(9))
1320 		return BIT(9) | (value / 16);
1321 
1322 	return value;
1323 }
1324 
1325 static u16 vsc9953_wm_dec(u16 wm)
1326 {
1327 	WARN_ON(wm & ~GENMASK(9, 0));
1328 
1329 	if (wm & BIT(9))
1330 		return (wm & GENMASK(8, 0)) * 16;
1331 
1332 	return wm;
1333 }
1334 
1335 static void vsc9953_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
1336 {
1337 	*inuse = (val & GENMASK(25, 13)) >> 13;
1338 	*maxuse = val & GENMASK(12, 0);
1339 }
1340 
1341 static const struct ocelot_ops vsc9953_ops = {
1342 	.reset			= vsc9953_reset,
1343 	.wm_enc			= vsc9953_wm_enc,
1344 	.wm_dec			= vsc9953_wm_dec,
1345 	.wm_stat		= vsc9953_wm_stat,
1346 	.port_to_netdev		= felix_port_to_netdev,
1347 	.netdev_to_port		= felix_netdev_to_port,
1348 };
1349 
1350 static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
1351 {
1352 	struct felix *felix = ocelot_to_felix(ocelot);
1353 	struct device *dev = ocelot->dev;
1354 	struct mii_bus *bus;
1355 	int port;
1356 	int rc;
1357 
1358 	felix->pcs = devm_kcalloc(dev, felix->info->num_ports,
1359 				  sizeof(struct phylink_pcs *),
1360 				  GFP_KERNEL);
1361 	if (!felix->pcs) {
1362 		dev_err(dev, "failed to allocate array for PCS PHYs\n");
1363 		return -ENOMEM;
1364 	}
1365 
1366 	rc = mscc_miim_setup(dev, &bus, "VSC9953 internal MDIO bus",
1367 			     ocelot->targets[GCB],
1368 			     ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK]);
1369 
1370 	if (rc) {
1371 		dev_err(dev, "failed to setup MDIO bus\n");
1372 		return rc;
1373 	}
1374 
1375 	/* Needed in order to initialize the bus mutex lock */
1376 	rc = devm_of_mdiobus_register(dev, bus, NULL);
1377 	if (rc < 0) {
1378 		dev_err(dev, "failed to register MDIO bus\n");
1379 		return rc;
1380 	}
1381 
1382 	felix->imdio = bus;
1383 
1384 	for (port = 0; port < felix->info->num_ports; port++) {
1385 		struct ocelot_port *ocelot_port = ocelot->ports[port];
1386 		struct phylink_pcs *phylink_pcs;
1387 		struct mdio_device *mdio_device;
1388 		int addr = port + 4;
1389 
1390 		if (dsa_is_unused_port(felix->ds, port))
1391 			continue;
1392 
1393 		if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
1394 			continue;
1395 
1396 		mdio_device = mdio_device_create(felix->imdio, addr);
1397 		if (IS_ERR(mdio_device))
1398 			continue;
1399 
1400 		phylink_pcs = lynx_pcs_create(mdio_device);
1401 		if (!phylink_pcs) {
1402 			mdio_device_free(mdio_device);
1403 			continue;
1404 		}
1405 
1406 		felix->pcs[port] = phylink_pcs;
1407 
1408 		dev_info(dev, "Found PCS at internal MDIO address %d\n", addr);
1409 	}
1410 
1411 	return 0;
1412 }
1413 
1414 static void vsc9953_mdio_bus_free(struct ocelot *ocelot)
1415 {
1416 	struct felix *felix = ocelot_to_felix(ocelot);
1417 	int port;
1418 
1419 	for (port = 0; port < ocelot->num_phys_ports; port++) {
1420 		struct phylink_pcs *phylink_pcs = felix->pcs[port];
1421 		struct mdio_device *mdio_device;
1422 
1423 		if (!phylink_pcs)
1424 			continue;
1425 
1426 		mdio_device = lynx_get_mdio_device(phylink_pcs);
1427 		mdio_device_free(mdio_device);
1428 		lynx_pcs_destroy(phylink_pcs);
1429 	}
1430 
1431 	/* mdiobus_unregister and mdiobus_free handled by devres */
1432 }
1433 
1434 static const struct felix_info seville_info_vsc9953 = {
1435 	.target_io_res		= vsc9953_target_io_res,
1436 	.port_io_res		= vsc9953_port_io_res,
1437 	.regfields		= vsc9953_regfields,
1438 	.map			= vsc9953_regmap,
1439 	.ops			= &vsc9953_ops,
1440 	.stats_layout		= vsc9953_stats_layout,
1441 	.vcap			= vsc9953_vcap_props,
1442 	.vcap_pol_base		= VSC9953_VCAP_POLICER_BASE,
1443 	.vcap_pol_max		= VSC9953_VCAP_POLICER_MAX,
1444 	.vcap_pol_base2		= VSC9953_VCAP_POLICER_BASE2,
1445 	.vcap_pol_max2		= VSC9953_VCAP_POLICER_MAX2,
1446 	.num_mact_rows		= 2048,
1447 	.num_ports		= VSC9953_NUM_PORTS,
1448 	.num_tx_queues		= OCELOT_NUM_TC,
1449 	.mdio_bus_alloc		= vsc9953_mdio_bus_alloc,
1450 	.mdio_bus_free		= vsc9953_mdio_bus_free,
1451 	.phylink_validate	= vsc9953_phylink_validate,
1452 	.port_modes		= vsc9953_port_modes,
1453 	.init_regmap		= ocelot_regmap_init,
1454 };
1455 
1456 static int seville_probe(struct platform_device *pdev)
1457 {
1458 	struct dsa_switch *ds;
1459 	struct ocelot *ocelot;
1460 	struct resource *res;
1461 	struct felix *felix;
1462 	int err;
1463 
1464 	felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
1465 	if (!felix) {
1466 		err = -ENOMEM;
1467 		dev_err(&pdev->dev, "Failed to allocate driver memory\n");
1468 		goto err_alloc_felix;
1469 	}
1470 
1471 	platform_set_drvdata(pdev, felix);
1472 
1473 	ocelot = &felix->ocelot;
1474 	ocelot->dev = &pdev->dev;
1475 	ocelot->num_flooding_pgids = 1;
1476 	felix->info = &seville_info_vsc9953;
1477 
1478 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1479 	if (!res) {
1480 		err = -EINVAL;
1481 		dev_err(&pdev->dev, "Invalid resource\n");
1482 		goto err_alloc_felix;
1483 	}
1484 	felix->switch_base = res->start;
1485 
1486 	ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
1487 	if (!ds) {
1488 		err = -ENOMEM;
1489 		dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
1490 		goto err_alloc_ds;
1491 	}
1492 
1493 	ds->dev = &pdev->dev;
1494 	ds->num_ports = felix->info->num_ports;
1495 	ds->ops = &felix_switch_ops;
1496 	ds->priv = ocelot;
1497 	felix->ds = ds;
1498 	felix->tag_proto = DSA_TAG_PROTO_SEVILLE;
1499 
1500 	err = dsa_register_switch(ds);
1501 	if (err) {
1502 		dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
1503 		goto err_register_ds;
1504 	}
1505 
1506 	return 0;
1507 
1508 err_register_ds:
1509 	kfree(ds);
1510 err_alloc_ds:
1511 err_alloc_felix:
1512 	kfree(felix);
1513 	return err;
1514 }
1515 
1516 static int seville_remove(struct platform_device *pdev)
1517 {
1518 	struct felix *felix = platform_get_drvdata(pdev);
1519 
1520 	if (!felix)
1521 		return 0;
1522 
1523 	dsa_unregister_switch(felix->ds);
1524 
1525 	kfree(felix->ds);
1526 	kfree(felix);
1527 
1528 	platform_set_drvdata(pdev, NULL);
1529 
1530 	return 0;
1531 }
1532 
1533 static void seville_shutdown(struct platform_device *pdev)
1534 {
1535 	struct felix *felix = platform_get_drvdata(pdev);
1536 
1537 	if (!felix)
1538 		return;
1539 
1540 	dsa_switch_shutdown(felix->ds);
1541 
1542 	platform_set_drvdata(pdev, NULL);
1543 }
1544 
1545 static const struct of_device_id seville_of_match[] = {
1546 	{ .compatible = "mscc,vsc9953-switch" },
1547 	{ },
1548 };
1549 MODULE_DEVICE_TABLE(of, seville_of_match);
1550 
1551 static struct platform_driver seville_vsc9953_driver = {
1552 	.probe		= seville_probe,
1553 	.remove		= seville_remove,
1554 	.shutdown	= seville_shutdown,
1555 	.driver = {
1556 		.name		= "mscc_seville",
1557 		.of_match_table	= of_match_ptr(seville_of_match),
1558 	},
1559 };
1560 module_platform_driver(seville_vsc9953_driver);
1561 
1562 MODULE_DESCRIPTION("Seville Switch driver");
1563 MODULE_LICENSE("GPL v2");
1564