xref: /linux/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c (revision fcc79e1714e8c2b8e216dc3149812edd37884eef)
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver VCAP implementation
3  *
4  * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
5  *
6  * The Sparx5 Chip Register Model can be browsed at this location:
7  * https://github.com/microchip-ung/sparx-5_reginfo
8  */
9 
10 #include "vcap_api_debugfs.h"
11 #include "sparx5_main_regs.h"
12 #include "sparx5_main.h"
13 #include "sparx5_vcap_impl.h"
14 #include "sparx5_vcap_ag_api.h"
15 #include "sparx5_vcap_debugfs.h"
16 
17 #define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
18 #define STREAMSIZE (64 * 4)  /* bytes in the VCAP cache area */
19 
20 #define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
21 	(ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
22 	 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
23 	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(_v4_mc) | \
24 	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(_v4_uc) | \
25 	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(_v6_mc) | \
26 	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
27 	 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
28 
29 #define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
30 	(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
31 	ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
32 	ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(_ipv4) | \
33 	ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(_ipv6) | \
34 	ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_SET(_mpls_uc) | \
35 	ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
36 	ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
37 
38 #define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
39 #define SPARX5_STAT_ESDX_GRN_PKTS  0x300
40 #define SPARX5_STAT_ESDX_YEL_PKTS  0x301
41 
42 #define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
43 	(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
44 	EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
45 	EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
46 	EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
47 
48 const struct sparx5_vcap_inst sparx5_vcap_inst_cfg[] = {
49 	{
50 		.vtype = VCAP_TYPE_IS0, /* CLM-0 */
51 		.vinst = 0,
52 		.map_id = 1,
53 		.lookups = SPARX5_IS0_LOOKUPS,
54 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
55 		.first_cid = SPARX5_VCAP_CID_IS0_L0,
56 		.last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
57 		.blockno = 8, /* Maps block 8-9 */
58 		.blocks = 2,
59 		.ingress = true,
60 	},
61 	{
62 		.vtype = VCAP_TYPE_IS0, /* CLM-1 */
63 		.vinst = 1,
64 		.map_id = 2,
65 		.lookups = SPARX5_IS0_LOOKUPS,
66 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
67 		.first_cid = SPARX5_VCAP_CID_IS0_L2,
68 		.last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
69 		.blockno = 6, /* Maps block 6-7 */
70 		.blocks = 2,
71 		.ingress = true,
72 	},
73 	{
74 		.vtype = VCAP_TYPE_IS0, /* CLM-2 */
75 		.vinst = 2,
76 		.map_id = 3,
77 		.lookups = SPARX5_IS0_LOOKUPS,
78 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
79 		.first_cid = SPARX5_VCAP_CID_IS0_L4,
80 		.last_cid = SPARX5_VCAP_CID_IS0_MAX,
81 		.blockno = 4, /* Maps block 4-5 */
82 		.blocks = 2,
83 		.ingress = true,
84 	},
85 	{
86 		.vtype = VCAP_TYPE_IS2, /* IS2-0 */
87 		.vinst = 0,
88 		.map_id = 4,
89 		.lookups = SPARX5_IS2_LOOKUPS,
90 		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
91 		.first_cid = SPARX5_VCAP_CID_IS2_L0,
92 		.last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
93 		.blockno = 0, /* Maps block 0-1 */
94 		.blocks = 2,
95 		.ingress = true,
96 	},
97 	{
98 		.vtype = VCAP_TYPE_IS2, /* IS2-1 */
99 		.vinst = 1,
100 		.map_id = 5,
101 		.lookups = SPARX5_IS2_LOOKUPS,
102 		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
103 		.first_cid = SPARX5_VCAP_CID_IS2_L2,
104 		.last_cid = SPARX5_VCAP_CID_IS2_MAX,
105 		.blockno = 2, /* Maps block 2-3 */
106 		.blocks = 2,
107 		.ingress = true,
108 	},
109 	{
110 		.vtype = VCAP_TYPE_ES0,
111 		.lookups = SPARX5_ES0_LOOKUPS,
112 		.lookups_per_instance = SPARX5_ES0_LOOKUPS,
113 		.first_cid = SPARX5_VCAP_CID_ES0_L0,
114 		.last_cid = SPARX5_VCAP_CID_ES0_MAX,
115 		.count = 4096, /* Addresses according to datasheet */
116 		.ingress = false,
117 	},
118 	{
119 		.vtype = VCAP_TYPE_ES2,
120 		.lookups = SPARX5_ES2_LOOKUPS,
121 		.lookups_per_instance = SPARX5_ES2_LOOKUPS,
122 		.first_cid = SPARX5_VCAP_CID_ES2_L0,
123 		.last_cid = SPARX5_VCAP_CID_ES2_MAX,
124 		.count = 12288, /* Addresses according to datasheet */
125 		.ingress = false,
126 	},
127 };
128 
129 /* These protocols have dedicated keysets in IS0 and a TC dissector */
130 static u16 sparx5_vcap_is0_known_etypes[] = {
131 	ETH_P_ALL,
132 	ETH_P_IP,
133 	ETH_P_IPV6,
134 };
135 
136 /* These protocols have dedicated keysets in IS2 and a TC dissector */
137 static u16 sparx5_vcap_is2_known_etypes[] = {
138 	ETH_P_ALL,
139 	ETH_P_ARP,
140 	ETH_P_IP,
141 	ETH_P_IPV6,
142 };
143 
144 /* These protocols have dedicated keysets in ES2 and a TC dissector */
145 static u16 sparx5_vcap_es2_known_etypes[] = {
146 	ETH_P_ALL,
147 	ETH_P_ARP,
148 	ETH_P_IP,
149 	ETH_P_IPV6,
150 };
151 
152 static void sparx5_vcap_type_err(struct sparx5 *sparx5,
153 				 struct vcap_admin *admin,
154 				 const char *fname)
155 {
156 	pr_err("%s: vcap type: %s not supported\n",
157 	       fname, sparx5_vcaps[admin->vtype].name);
158 }
159 
160 /* Await the super VCAP completion of the current operation */
161 static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
162 {
163 	u32 value;
164 
165 	read_poll_timeout(spx5_rd, value,
166 			  !VCAP_SUPER_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
167 			  false, sparx5, VCAP_SUPER_CTRL);
168 }
169 
170 /* Await the ES0 VCAP completion of the current operation */
171 static void sparx5_vcap_wait_es0_update(struct sparx5 *sparx5)
172 {
173 	u32 value;
174 
175 	read_poll_timeout(spx5_rd, value,
176 			  !VCAP_ES0_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
177 			  false, sparx5, VCAP_ES0_CTRL);
178 }
179 
180 /* Await the ES2 VCAP completion of the current operation */
181 static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
182 {
183 	u32 value;
184 
185 	read_poll_timeout(spx5_rd, value,
186 			  !VCAP_ES2_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
187 			  false, sparx5, VCAP_ES2_CTRL);
188 }
189 
190 /* Initializing a VCAP address range */
191 static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
192 				    struct vcap_admin *admin,
193 				    u32 addr, u32 count)
194 {
195 	u32 size = count - 1;
196 
197 	switch (admin->vtype) {
198 	case VCAP_TYPE_IS0:
199 	case VCAP_TYPE_IS2:
200 		spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
201 			VCAP_SUPER_CFG_MV_SIZE_SET(size),
202 			sparx5, VCAP_SUPER_CFG);
203 		spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
204 			VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
205 			VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
206 			VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
207 			VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
208 			VCAP_SUPER_CTRL_CLEAR_CACHE_SET(true) |
209 			VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
210 			sparx5, VCAP_SUPER_CTRL);
211 		sparx5_vcap_wait_super_update(sparx5);
212 		break;
213 	case VCAP_TYPE_ES0:
214 		spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
215 				VCAP_ES0_CFG_MV_SIZE_SET(size),
216 			sparx5, VCAP_ES0_CFG);
217 		spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
218 				VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
219 				VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
220 				VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
221 				VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
222 				VCAP_ES0_CTRL_CLEAR_CACHE_SET(true) |
223 				VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
224 			sparx5, VCAP_ES0_CTRL);
225 		sparx5_vcap_wait_es0_update(sparx5);
226 		break;
227 	case VCAP_TYPE_ES2:
228 		spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
229 			VCAP_ES2_CFG_MV_SIZE_SET(size),
230 			sparx5, VCAP_ES2_CFG);
231 		spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
232 			VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
233 			VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
234 			VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
235 			VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
236 			VCAP_ES2_CTRL_CLEAR_CACHE_SET(true) |
237 			VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
238 			sparx5, VCAP_ES2_CTRL);
239 		sparx5_vcap_wait_es2_update(sparx5);
240 		break;
241 	default:
242 		sparx5_vcap_type_err(sparx5, admin, __func__);
243 		break;
244 	}
245 }
246 
247 /* Initializing VCAP rule data area */
248 static void sparx5_vcap_block_init(struct sparx5 *sparx5,
249 				   struct vcap_admin *admin)
250 {
251 	_sparx5_vcap_range_init(sparx5, admin, admin->first_valid_addr,
252 				admin->last_valid_addr -
253 					admin->first_valid_addr);
254 }
255 
256 /* Get the keyset name from the sparx5 VCAP model */
257 static const char *sparx5_vcap_keyset_name(struct net_device *ndev,
258 					   enum vcap_keyfield_set keyset)
259 {
260 	struct sparx5_port *port = netdev_priv(ndev);
261 
262 	return vcap_keyset_name(port->sparx5->vcap_ctrl, keyset);
263 }
264 
265 /* Check if this is the first lookup of IS0 */
266 static bool sparx5_vcap_is0_is_first_chain(struct vcap_rule *rule)
267 {
268 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L0 &&
269 		rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L1) ||
270 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L2 &&
271 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L3)) ||
272 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L4 &&
273 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L5));
274 }
275 
276 /* Check if this is the first lookup of IS2 */
277 static bool sparx5_vcap_is2_is_first_chain(struct vcap_rule *rule)
278 {
279 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L0 &&
280 		rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L1) ||
281 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L2 &&
282 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L3));
283 }
284 
285 static bool sparx5_vcap_es2_is_first_chain(struct vcap_rule *rule)
286 {
287 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_ES2_L0 &&
288 		rule->vcap_chain_id < SPARX5_VCAP_CID_ES2_L1);
289 }
290 
291 /* Set the narrow range ingress port mask on a rule */
292 static void sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule *rule,
293 						    struct net_device *ndev)
294 {
295 	struct sparx5_port *port = netdev_priv(ndev);
296 	u32 port_mask;
297 	u32 range;
298 
299 	range = port->portno / BITS_PER_TYPE(u32);
300 	/* Port bit set to match-any */
301 	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
302 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_SEL, 0, 0xf);
303 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, range, 0xf);
304 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, port_mask);
305 }
306 
307 /* Set the wide range ingress port mask on a rule */
308 static void sparx5_vcap_add_wide_port_mask(struct vcap_rule *rule,
309 					   struct net_device *ndev)
310 {
311 	struct sparx5_port *port = netdev_priv(ndev);
312 	struct vcap_u72_key port_mask;
313 	u32 range;
314 
315 	/* Port bit set to match-any */
316 	memset(port_mask.value, 0, sizeof(port_mask.value));
317 	memset(port_mask.mask, 0xff, sizeof(port_mask.mask));
318 	range = port->portno / BITS_PER_BYTE;
319 	port_mask.mask[range] = ~BIT(port->portno % BITS_PER_BYTE);
320 	vcap_rule_add_key_u72(rule, VCAP_KF_IF_IGR_PORT_MASK, &port_mask);
321 }
322 
323 static void sparx5_vcap_add_egress_range_port_mask(struct vcap_rule *rule,
324 						   struct net_device *ndev)
325 {
326 	struct sparx5_port *port = netdev_priv(ndev);
327 	u32 port_mask;
328 	u32 range;
329 
330 	/* Mask range selects:
331 	 * 0-2: Physical/Logical egress port number 0-31, 32–63, 64.
332 	 * 3-5: Virtual Interface Number 0-31, 32-63, 64.
333 	 * 6: CPU queue Number 0-7.
334 	 *
335 	 * Use physical/logical port ranges (0-2)
336 	 */
337 	range = port->portno / BITS_PER_TYPE(u32);
338 	/* Port bit set to match-any */
339 	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
340 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK_RNG, range, 0xf);
341 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK, 0, port_mask);
342 }
343 
344 /* Convert IS0 chain id to vcap lookup id */
345 static int sparx5_vcap_is0_cid_to_lookup(int cid)
346 {
347 	int lookup = 0;
348 
349 	if (cid >= SPARX5_VCAP_CID_IS0_L1 && cid < SPARX5_VCAP_CID_IS0_L2)
350 		lookup = 1;
351 	else if (cid >= SPARX5_VCAP_CID_IS0_L2 && cid < SPARX5_VCAP_CID_IS0_L3)
352 		lookup = 2;
353 	else if (cid >= SPARX5_VCAP_CID_IS0_L3 && cid < SPARX5_VCAP_CID_IS0_L4)
354 		lookup = 3;
355 	else if (cid >= SPARX5_VCAP_CID_IS0_L4 && cid < SPARX5_VCAP_CID_IS0_L5)
356 		lookup = 4;
357 	else if (cid >= SPARX5_VCAP_CID_IS0_L5 && cid < SPARX5_VCAP_CID_IS0_MAX)
358 		lookup = 5;
359 
360 	return lookup;
361 }
362 
363 /* Convert IS2 chain id to vcap lookup id */
364 static int sparx5_vcap_is2_cid_to_lookup(int cid)
365 {
366 	int lookup = 0;
367 
368 	if (cid >= SPARX5_VCAP_CID_IS2_L1 && cid < SPARX5_VCAP_CID_IS2_L2)
369 		lookup = 1;
370 	else if (cid >= SPARX5_VCAP_CID_IS2_L2 && cid < SPARX5_VCAP_CID_IS2_L3)
371 		lookup = 2;
372 	else if (cid >= SPARX5_VCAP_CID_IS2_L3 && cid < SPARX5_VCAP_CID_IS2_MAX)
373 		lookup = 3;
374 
375 	return lookup;
376 }
377 
378 /* Convert ES2 chain id to vcap lookup id */
379 static int sparx5_vcap_es2_cid_to_lookup(int cid)
380 {
381 	int lookup = 0;
382 
383 	if (cid >= SPARX5_VCAP_CID_ES2_L1)
384 		lookup = 1;
385 
386 	return lookup;
387 }
388 
389 /* Add ethernet type IS0 keyset to a list */
390 static void
391 sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list *keysetlist,
392 				       u32 value)
393 {
394 	switch (ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value)) {
395 	case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
396 		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_7TUPLE);
397 		break;
398 	case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
399 		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_5TUPLE_IP4);
400 		break;
401 	}
402 }
403 
404 /* Return the list of keysets for the vcap port configuration */
405 static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
406 					    int lookup,
407 					    struct vcap_keyset_list *keysetlist,
408 					    u16 l3_proto)
409 {
410 	struct sparx5_port *port = netdev_priv(ndev);
411 	struct sparx5 *sparx5 = port->sparx5;
412 	int portno = port->portno;
413 	u32 value;
414 
415 	value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
416 
417 	/* Collect all keysets for the port in a list */
418 	if (l3_proto == ETH_P_ALL)
419 		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
420 
421 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
422 		switch (ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value)) {
423 		case VCAP_IS0_PS_ETYPE_DEFAULT:
424 			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
425 							       value);
426 			break;
427 		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
428 			vcap_keyset_list_add(keysetlist,
429 					     VCAP_KFS_NORMAL_7TUPLE);
430 			break;
431 		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
432 			vcap_keyset_list_add(keysetlist,
433 					     VCAP_KFS_NORMAL_5TUPLE_IP4);
434 			break;
435 		}
436 
437 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6)
438 		switch (ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value)) {
439 		case VCAP_IS0_PS_ETYPE_DEFAULT:
440 			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
441 							       value);
442 			break;
443 		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
444 			vcap_keyset_list_add(keysetlist,
445 					     VCAP_KFS_NORMAL_7TUPLE);
446 			break;
447 		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
448 			vcap_keyset_list_add(keysetlist,
449 					     VCAP_KFS_NORMAL_5TUPLE_IP4);
450 			break;
451 		}
452 
453 	if (l3_proto != ETH_P_IP && l3_proto != ETH_P_IPV6)
454 		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
455 	return 0;
456 }
457 
458 /* Return the list of keysets for the vcap port configuration */
459 static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
460 					    int lookup,
461 					    struct vcap_keyset_list *keysetlist,
462 					    u16 l3_proto)
463 {
464 	struct sparx5_port *port = netdev_priv(ndev);
465 	struct sparx5 *sparx5 = port->sparx5;
466 	int portno = port->portno;
467 	u32 value;
468 
469 	value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
470 
471 	/* Collect all keysets for the port in a list */
472 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
473 		switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
474 		case VCAP_IS2_PS_ARP_MAC_ETYPE:
475 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
476 			break;
477 		case VCAP_IS2_PS_ARP_ARP:
478 			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
479 			break;
480 		}
481 	}
482 
483 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
484 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
485 		case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
486 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
487 			break;
488 		case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
489 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
490 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
491 			break;
492 		case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
493 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
494 			break;
495 		}
496 
497 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
498 		case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
499 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
500 			break;
501 		case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
502 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
503 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
504 			break;
505 		case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
506 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
507 			break;
508 		}
509 	}
510 
511 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
512 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
513 		case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
514 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
515 			break;
516 		case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
517 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
518 			break;
519 		case VCAP_IS2_PS_IPV6_UC_IP6_STD:
520 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
521 			break;
522 		case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
523 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
524 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
525 			break;
526 		}
527 
528 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
529 		case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
530 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
531 			break;
532 		case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
533 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
534 			break;
535 		case VCAP_IS2_PS_IPV6_MC_IP6_STD:
536 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
537 			break;
538 		case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
539 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
540 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
541 			break;
542 		case VCAP_IS2_PS_IPV6_MC_IP6_VID:
543 			/* Not used */
544 			break;
545 		}
546 	}
547 
548 	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
549 	    l3_proto != ETH_P_IPV6) {
550 		switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
551 		case VCAP_IS2_PS_NONETH_MAC_ETYPE:
552 			/* IS2 non-classified frames generate MAC_ETYPE */
553 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
554 			break;
555 		}
556 	}
557 	return 0;
558 }
559 
560 /* Return the keysets for the vcap port IP4 traffic class configuration */
561 static void
562 sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
563 				      u32 value)
564 {
565 	switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
566 	case VCAP_ES2_PS_IPV4_MAC_ETYPE:
567 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
568 		break;
569 	case VCAP_ES2_PS_IPV4_IP_7TUPLE:
570 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
571 		break;
572 	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
573 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
574 		break;
575 	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
576 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
577 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
578 		break;
579 	case VCAP_ES2_PS_IPV4_IP4_VID:
580 		/* Not used */
581 		break;
582 	case VCAP_ES2_PS_IPV4_IP4_OTHER:
583 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
584 		break;
585 	}
586 }
587 
588 /* Return the list of keysets for the vcap port configuration */
589 static int sparx5_vcap_es0_get_port_keysets(struct net_device *ndev,
590 					    struct vcap_keyset_list *keysetlist,
591 					    u16 l3_proto)
592 {
593 	struct sparx5_port *port = netdev_priv(ndev);
594 	struct sparx5 *sparx5 = port->sparx5;
595 	int portno = port->portno;
596 	u32 value;
597 
598 	value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(portno));
599 
600 	/* Collect all keysets for the port in a list */
601 	switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
602 	case VCAP_ES0_PS_NORMAL_SELECTION:
603 	case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
604 		vcap_keyset_list_add(keysetlist, VCAP_KFS_ISDX);
605 		break;
606 	default:
607 		break;
608 	}
609 	return 0;
610 }
611 
612 /* Return the list of keysets for the vcap port configuration */
613 static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
614 					    int lookup,
615 					    struct vcap_keyset_list *keysetlist,
616 					    u16 l3_proto)
617 {
618 	struct sparx5_port *port = netdev_priv(ndev);
619 	struct sparx5 *sparx5 = port->sparx5;
620 	int portno = port->portno;
621 	u32 value;
622 
623 	value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(portno, lookup));
624 
625 	/* Collect all keysets for the port in a list */
626 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
627 		switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
628 		case VCAP_ES2_PS_ARP_MAC_ETYPE:
629 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
630 			break;
631 		case VCAP_ES2_PS_ARP_ARP:
632 			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
633 			break;
634 		}
635 	}
636 
637 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
638 		sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist, value);
639 
640 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
641 		switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
642 		case VCAP_ES2_PS_IPV6_MAC_ETYPE:
643 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
644 			break;
645 		case VCAP_ES2_PS_IPV6_IP_7TUPLE:
646 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
647 			break;
648 		case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
649 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
650 			break;
651 		case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
652 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
653 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
654 			break;
655 		case VCAP_ES2_PS_IPV6_IP6_VID:
656 			/* Not used */
657 			break;
658 		case VCAP_ES2_PS_IPV6_IP6_STD:
659 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
660 			break;
661 		case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
662 			sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist,
663 							      value);
664 			break;
665 		}
666 	}
667 
668 	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
669 	    l3_proto != ETH_P_IPV6) {
670 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
671 	}
672 	return 0;
673 }
674 
675 /* Get the port keyset for the vcap lookup */
676 int sparx5_vcap_get_port_keyset(struct net_device *ndev,
677 				struct vcap_admin *admin,
678 				int cid,
679 				u16 l3_proto,
680 				struct vcap_keyset_list *kslist)
681 {
682 	int lookup, err = -EINVAL;
683 	struct sparx5_port *port;
684 
685 	switch (admin->vtype) {
686 	case VCAP_TYPE_IS0:
687 		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
688 		err = sparx5_vcap_is0_get_port_keysets(ndev, lookup, kslist,
689 						       l3_proto);
690 		break;
691 	case VCAP_TYPE_IS2:
692 		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
693 		err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
694 						       l3_proto);
695 		break;
696 	case VCAP_TYPE_ES0:
697 		err = sparx5_vcap_es0_get_port_keysets(ndev, kslist, l3_proto);
698 		break;
699 	case VCAP_TYPE_ES2:
700 		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
701 		err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
702 						       l3_proto);
703 		break;
704 	default:
705 		port = netdev_priv(ndev);
706 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
707 		break;
708 	}
709 	return err;
710 }
711 
712 /* Check if the ethertype is supported by the vcap port classification */
713 bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
714 {
715 	const u16 *known_etypes;
716 	int size, idx;
717 
718 	switch (admin->vtype) {
719 	case VCAP_TYPE_IS0:
720 		known_etypes = sparx5_vcap_is0_known_etypes;
721 		size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
722 		break;
723 	case VCAP_TYPE_IS2:
724 		known_etypes = sparx5_vcap_is2_known_etypes;
725 		size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
726 		break;
727 	case VCAP_TYPE_ES0:
728 		return true;
729 	case VCAP_TYPE_ES2:
730 		known_etypes = sparx5_vcap_es2_known_etypes;
731 		size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
732 		break;
733 	default:
734 		return false;
735 	}
736 	for (idx = 0; idx < size; ++idx)
737 		if (known_etypes[idx] == etype)
738 			return true;
739 	return false;
740 }
741 
742 /* API callback used for validating a field keyset (check the port keysets) */
743 static enum vcap_keyfield_set
744 sparx5_vcap_validate_keyset(struct net_device *ndev,
745 			    struct vcap_admin *admin,
746 			    struct vcap_rule *rule,
747 			    struct vcap_keyset_list *kslist,
748 			    u16 l3_proto)
749 {
750 	struct vcap_keyset_list keysetlist = {};
751 	enum vcap_keyfield_set keysets[10] = {};
752 	struct sparx5_port *port;
753 	int idx, jdx, lookup;
754 
755 	if (!kslist || kslist->cnt == 0)
756 		return VCAP_KFS_NO_VALUE;
757 
758 	keysetlist.max = ARRAY_SIZE(keysets);
759 	keysetlist.keysets = keysets;
760 
761 	/* Get a list of currently configured keysets in the lookups */
762 	switch (admin->vtype) {
763 	case VCAP_TYPE_IS0:
764 		lookup = sparx5_vcap_is0_cid_to_lookup(rule->vcap_chain_id);
765 		sparx5_vcap_is0_get_port_keysets(ndev, lookup, &keysetlist,
766 						 l3_proto);
767 		break;
768 	case VCAP_TYPE_IS2:
769 		lookup = sparx5_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
770 		sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
771 						 l3_proto);
772 		break;
773 	case VCAP_TYPE_ES0:
774 		sparx5_vcap_es0_get_port_keysets(ndev, &keysetlist, l3_proto);
775 		break;
776 	case VCAP_TYPE_ES2:
777 		lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
778 		sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
779 						 l3_proto);
780 		break;
781 	default:
782 		port = netdev_priv(ndev);
783 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
784 		break;
785 	}
786 
787 	/* Check if there is a match and return the match */
788 	for (idx = 0; idx < kslist->cnt; ++idx)
789 		for (jdx = 0; jdx < keysetlist.cnt; ++jdx)
790 			if (kslist->keysets[idx] == keysets[jdx])
791 				return kslist->keysets[idx];
792 
793 	pr_err("%s:%d: %s not supported in port key selection\n",
794 	       __func__, __LINE__,
795 	       sparx5_vcap_keyset_name(ndev, kslist->keysets[0]));
796 
797 	return -ENOENT;
798 }
799 
800 static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
801 						   struct vcap_admin *admin,
802 						   struct vcap_rule *rule)
803 {
804 	const struct vcap_field *field;
805 	bool is_first;
806 
807 	/* Add ingress port mask matching the net device */
808 	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_IGR_PORT_MASK);
809 	if (field && field->width == SPX5_PORTS)
810 		sparx5_vcap_add_wide_port_mask(rule, ndev);
811 	else if (field && field->width == BITS_PER_TYPE(u32))
812 		sparx5_vcap_add_ingress_range_port_mask(rule, ndev);
813 	else
814 		pr_err("%s:%d: %s: could not add an ingress port mask for: %s\n",
815 		       __func__, __LINE__, netdev_name(ndev),
816 		       sparx5_vcap_keyset_name(ndev, rule->keyset));
817 
818 	if (admin->vtype == VCAP_TYPE_IS0)
819 		is_first = sparx5_vcap_is0_is_first_chain(rule);
820 	else
821 		is_first = sparx5_vcap_is2_is_first_chain(rule);
822 
823 	/* Add key that selects the first/second lookup */
824 	if (is_first)
825 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
826 				      VCAP_BIT_1);
827 	else
828 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
829 				      VCAP_BIT_0);
830 }
831 
832 static void sparx5_vcap_es0_add_default_fields(struct net_device *ndev,
833 					       struct vcap_admin *admin,
834 					       struct vcap_rule *rule)
835 {
836 	struct sparx5_port *port = netdev_priv(ndev);
837 
838 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, port->portno, ~0);
839 	/* Match untagged frames if there was no VLAN key */
840 	vcap_rule_add_key_u32(rule, VCAP_KF_8021Q_TPID, SPX5_TPID_SEL_UNTAGGED,
841 			      ~0);
842 }
843 
844 static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
845 					       struct vcap_admin *admin,
846 					       struct vcap_rule *rule)
847 {
848 	const struct vcap_field *field;
849 	bool is_first;
850 
851 	/* Add egress port mask matching the net device */
852 	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
853 	if (field)
854 		sparx5_vcap_add_egress_range_port_mask(rule, ndev);
855 
856 	/* Add key that selects the first/second lookup */
857 	is_first = sparx5_vcap_es2_is_first_chain(rule);
858 
859 	if (is_first)
860 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
861 				      VCAP_BIT_1);
862 	else
863 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
864 				      VCAP_BIT_0);
865 }
866 
867 /* API callback used for adding default fields to a rule */
868 static void sparx5_vcap_add_default_fields(struct net_device *ndev,
869 					   struct vcap_admin *admin,
870 					   struct vcap_rule *rule)
871 {
872 	struct sparx5_port *port;
873 
874 	/* add the lookup bit */
875 	switch (admin->vtype) {
876 	case VCAP_TYPE_IS0:
877 	case VCAP_TYPE_IS2:
878 		sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
879 		break;
880 	case VCAP_TYPE_ES0:
881 		sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
882 		break;
883 	case VCAP_TYPE_ES2:
884 		sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
885 		break;
886 	default:
887 		port = netdev_priv(ndev);
888 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
889 		break;
890 	}
891 }
892 
893 /* API callback used for erasing the vcap cache area (not the register area) */
894 static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
895 {
896 	memset(admin->cache.keystream, 0, STREAMSIZE);
897 	memset(admin->cache.maskstream, 0, STREAMSIZE);
898 	memset(admin->cache.actionstream, 0, STREAMSIZE);
899 	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
900 }
901 
902 static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
903 					struct vcap_admin *admin,
904 					enum vcap_selection sel,
905 					u32 start,
906 					u32 count)
907 {
908 	u32 *keystr, *mskstr, *actstr;
909 	int idx;
910 
911 	keystr = &admin->cache.keystream[start];
912 	mskstr = &admin->cache.maskstream[start];
913 	actstr = &admin->cache.actionstream[start];
914 
915 	switch (sel) {
916 	case VCAP_SEL_ENTRY:
917 		for (idx = 0; idx < count; ++idx) {
918 			/* Avoid 'match-off' by setting value & mask */
919 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
920 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
921 			spx5_wr(~mskstr[idx], sparx5,
922 				VCAP_SUPER_VCAP_MASK_DAT(idx));
923 		}
924 		break;
925 	case VCAP_SEL_ACTION:
926 		for (idx = 0; idx < count; ++idx)
927 			spx5_wr(actstr[idx], sparx5,
928 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
929 		break;
930 	case VCAP_SEL_ALL:
931 		pr_err("%s:%d: cannot write all streams at once\n",
932 		       __func__, __LINE__);
933 		break;
934 	default:
935 		break;
936 	}
937 
938 	if (sel & VCAP_SEL_COUNTER)
939 		spx5_wr(admin->cache.counter, sparx5,
940 			VCAP_SUPER_VCAP_CNT_DAT(0));
941 }
942 
943 static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
944 					struct vcap_admin *admin,
945 					enum vcap_selection sel,
946 					u32 start,
947 					u32 count)
948 {
949 	u32 *keystr, *mskstr, *actstr;
950 	int idx;
951 
952 	keystr = &admin->cache.keystream[start];
953 	mskstr = &admin->cache.maskstream[start];
954 	actstr = &admin->cache.actionstream[start];
955 
956 	switch (sel) {
957 	case VCAP_SEL_ENTRY:
958 		for (idx = 0; idx < count; ++idx) {
959 			/* Avoid 'match-off' by setting value & mask */
960 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
961 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
962 			spx5_wr(~mskstr[idx], sparx5,
963 				VCAP_SUPER_VCAP_MASK_DAT(idx));
964 		}
965 		break;
966 	case VCAP_SEL_ACTION:
967 		for (idx = 0; idx < count; ++idx)
968 			spx5_wr(actstr[idx], sparx5,
969 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
970 		break;
971 	case VCAP_SEL_ALL:
972 		pr_err("%s:%d: cannot write all streams at once\n",
973 		       __func__, __LINE__);
974 		break;
975 	default:
976 		break;
977 	}
978 	if (sel & VCAP_SEL_COUNTER) {
979 		start = start & 0xfff; /* counter limit */
980 		if (admin->vinst == 0)
981 			spx5_wr(admin->cache.counter, sparx5,
982 				ANA_ACL_CNT_A(start));
983 		else
984 			spx5_wr(admin->cache.counter, sparx5,
985 				ANA_ACL_CNT_B(start));
986 		spx5_wr(admin->cache.sticky, sparx5,
987 			VCAP_SUPER_VCAP_CNT_DAT(0));
988 	}
989 }
990 
991 /* Use ESDX counters located in the XQS */
992 static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
993 					  struct vcap_admin *admin, u32 id)
994 {
995 	mutex_lock(&sparx5->queue_stats_lock);
996 	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
997 	spx5_wr(admin->cache.counter, sparx5,
998 		XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
999 	spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1000 	mutex_unlock(&sparx5->queue_stats_lock);
1001 }
1002 
1003 static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
1004 					struct vcap_admin *admin,
1005 					enum vcap_selection sel,
1006 					u32 start,
1007 					u32 count)
1008 {
1009 	u32 *keystr, *mskstr, *actstr;
1010 	int idx;
1011 
1012 	keystr = &admin->cache.keystream[start];
1013 	mskstr = &admin->cache.maskstream[start];
1014 	actstr = &admin->cache.actionstream[start];
1015 
1016 	switch (sel) {
1017 	case VCAP_SEL_ENTRY:
1018 		for (idx = 0; idx < count; ++idx) {
1019 			/* Avoid 'match-off' by setting value & mask */
1020 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1021 				VCAP_ES0_VCAP_ENTRY_DAT(idx));
1022 			spx5_wr(~mskstr[idx], sparx5,
1023 				VCAP_ES0_VCAP_MASK_DAT(idx));
1024 		}
1025 		break;
1026 	case VCAP_SEL_ACTION:
1027 		for (idx = 0; idx < count; ++idx)
1028 			spx5_wr(actstr[idx], sparx5,
1029 				VCAP_ES0_VCAP_ACTION_DAT(idx));
1030 		break;
1031 	case VCAP_SEL_ALL:
1032 		pr_err("%s:%d: cannot write all streams at once\n",
1033 		       __func__, __LINE__);
1034 		break;
1035 	default:
1036 		break;
1037 	}
1038 	if (sel & VCAP_SEL_COUNTER) {
1039 		spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1040 		sparx5_es0_write_esdx_counter(sparx5, admin, start);
1041 	}
1042 }
1043 
1044 static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
1045 					struct vcap_admin *admin,
1046 					enum vcap_selection sel,
1047 					u32 start,
1048 					u32 count)
1049 {
1050 	u32 *keystr, *mskstr, *actstr;
1051 	int idx;
1052 
1053 	keystr = &admin->cache.keystream[start];
1054 	mskstr = &admin->cache.maskstream[start];
1055 	actstr = &admin->cache.actionstream[start];
1056 
1057 	switch (sel) {
1058 	case VCAP_SEL_ENTRY:
1059 		for (idx = 0; idx < count; ++idx) {
1060 			/* Avoid 'match-off' by setting value & mask */
1061 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1062 				VCAP_ES2_VCAP_ENTRY_DAT(idx));
1063 			spx5_wr(~mskstr[idx], sparx5,
1064 				VCAP_ES2_VCAP_MASK_DAT(idx));
1065 		}
1066 		break;
1067 	case VCAP_SEL_ACTION:
1068 		for (idx = 0; idx < count; ++idx)
1069 			spx5_wr(actstr[idx], sparx5,
1070 				VCAP_ES2_VCAP_ACTION_DAT(idx));
1071 		break;
1072 	case VCAP_SEL_ALL:
1073 		pr_err("%s:%d: cannot write all streams at once\n",
1074 		       __func__, __LINE__);
1075 		break;
1076 	default:
1077 		break;
1078 	}
1079 	if (sel & VCAP_SEL_COUNTER) {
1080 		start = start & 0x7ff; /* counter limit */
1081 		spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
1082 		spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1083 	}
1084 }
1085 
1086 /* API callback used for writing to the VCAP cache */
1087 static void sparx5_vcap_cache_write(struct net_device *ndev,
1088 				    struct vcap_admin *admin,
1089 				    enum vcap_selection sel,
1090 				    u32 start,
1091 				    u32 count)
1092 {
1093 	struct sparx5_port *port = netdev_priv(ndev);
1094 	struct sparx5 *sparx5 = port->sparx5;
1095 
1096 	switch (admin->vtype) {
1097 	case VCAP_TYPE_IS0:
1098 		sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
1099 		break;
1100 	case VCAP_TYPE_IS2:
1101 		sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
1102 		break;
1103 	case VCAP_TYPE_ES0:
1104 		sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
1105 		break;
1106 	case VCAP_TYPE_ES2:
1107 		sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
1108 		break;
1109 	default:
1110 		sparx5_vcap_type_err(sparx5, admin, __func__);
1111 		break;
1112 	}
1113 }
1114 
1115 static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
1116 				       struct vcap_admin *admin,
1117 				       enum vcap_selection sel,
1118 				       u32 start,
1119 				       u32 count)
1120 {
1121 	u32 *keystr, *mskstr, *actstr;
1122 	int idx;
1123 
1124 	keystr = &admin->cache.keystream[start];
1125 	mskstr = &admin->cache.maskstream[start];
1126 	actstr = &admin->cache.actionstream[start];
1127 
1128 	if (sel & VCAP_SEL_ENTRY) {
1129 		for (idx = 0; idx < count; ++idx) {
1130 			keystr[idx] = spx5_rd(sparx5,
1131 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1132 			mskstr[idx] = ~spx5_rd(sparx5,
1133 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1134 		}
1135 	}
1136 
1137 	if (sel & VCAP_SEL_ACTION)
1138 		for (idx = 0; idx < count; ++idx)
1139 			actstr[idx] = spx5_rd(sparx5,
1140 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1141 
1142 	if (sel & VCAP_SEL_COUNTER) {
1143 		admin->cache.counter =
1144 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1145 		admin->cache.sticky =
1146 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1147 	}
1148 }
1149 
1150 static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1151 				       struct vcap_admin *admin,
1152 				       enum vcap_selection sel,
1153 				       u32 start,
1154 				       u32 count)
1155 {
1156 	u32 *keystr, *mskstr, *actstr;
1157 	int idx;
1158 
1159 	keystr = &admin->cache.keystream[start];
1160 	mskstr = &admin->cache.maskstream[start];
1161 	actstr = &admin->cache.actionstream[start];
1162 
1163 	if (sel & VCAP_SEL_ENTRY) {
1164 		for (idx = 0; idx < count; ++idx) {
1165 			keystr[idx] = spx5_rd(sparx5,
1166 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1167 			mskstr[idx] = ~spx5_rd(sparx5,
1168 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1169 		}
1170 	}
1171 
1172 	if (sel & VCAP_SEL_ACTION)
1173 		for (idx = 0; idx < count; ++idx)
1174 			actstr[idx] = spx5_rd(sparx5,
1175 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1176 
1177 	if (sel & VCAP_SEL_COUNTER) {
1178 		start = start & 0xfff; /* counter limit */
1179 		if (admin->vinst == 0)
1180 			admin->cache.counter =
1181 				spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1182 		else
1183 			admin->cache.counter =
1184 				spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1185 		admin->cache.sticky =
1186 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1187 	}
1188 }
1189 
1190 /* Use ESDX counters located in the XQS */
1191 static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
1192 					 struct vcap_admin *admin, u32 id)
1193 {
1194 	u32 counter;
1195 
1196 	mutex_lock(&sparx5->queue_stats_lock);
1197 	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1198 	counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
1199 		spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1200 	mutex_unlock(&sparx5->queue_stats_lock);
1201 	if (counter)
1202 		admin->cache.counter = counter;
1203 }
1204 
1205 static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
1206 				       struct vcap_admin *admin,
1207 				       enum vcap_selection sel,
1208 				       u32 start,
1209 				       u32 count)
1210 {
1211 	u32 *keystr, *mskstr, *actstr;
1212 	int idx;
1213 
1214 	keystr = &admin->cache.keystream[start];
1215 	mskstr = &admin->cache.maskstream[start];
1216 	actstr = &admin->cache.actionstream[start];
1217 
1218 	if (sel & VCAP_SEL_ENTRY) {
1219 		for (idx = 0; idx < count; ++idx) {
1220 			keystr[idx] =
1221 				spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
1222 			mskstr[idx] =
1223 				~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
1224 		}
1225 	}
1226 
1227 	if (sel & VCAP_SEL_ACTION)
1228 		for (idx = 0; idx < count; ++idx)
1229 			actstr[idx] =
1230 				spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
1231 
1232 	if (sel & VCAP_SEL_COUNTER) {
1233 		admin->cache.counter =
1234 			spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1235 		admin->cache.sticky = admin->cache.counter;
1236 		sparx5_es0_read_esdx_counter(sparx5, admin, start);
1237 	}
1238 }
1239 
1240 static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1241 				       struct vcap_admin *admin,
1242 				       enum vcap_selection sel,
1243 				       u32 start,
1244 				       u32 count)
1245 {
1246 	u32 *keystr, *mskstr, *actstr;
1247 	int idx;
1248 
1249 	keystr = &admin->cache.keystream[start];
1250 	mskstr = &admin->cache.maskstream[start];
1251 	actstr = &admin->cache.actionstream[start];
1252 
1253 	if (sel & VCAP_SEL_ENTRY) {
1254 		for (idx = 0; idx < count; ++idx) {
1255 			keystr[idx] =
1256 				spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1257 			mskstr[idx] =
1258 				~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1259 		}
1260 	}
1261 
1262 	if (sel & VCAP_SEL_ACTION)
1263 		for (idx = 0; idx < count; ++idx)
1264 			actstr[idx] =
1265 				spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1266 
1267 	if (sel & VCAP_SEL_COUNTER) {
1268 		start = start & 0x7ff; /* counter limit */
1269 		admin->cache.counter =
1270 			spx5_rd(sparx5, EACL_ES2_CNT(start));
1271 		admin->cache.sticky =
1272 			spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1273 	}
1274 }
1275 
1276 /* API callback used for reading from the VCAP into the VCAP cache */
1277 static void sparx5_vcap_cache_read(struct net_device *ndev,
1278 				   struct vcap_admin *admin,
1279 				   enum vcap_selection sel,
1280 				   u32 start,
1281 				   u32 count)
1282 {
1283 	struct sparx5_port *port = netdev_priv(ndev);
1284 	struct sparx5 *sparx5 = port->sparx5;
1285 
1286 	switch (admin->vtype) {
1287 	case VCAP_TYPE_IS0:
1288 		sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1289 		break;
1290 	case VCAP_TYPE_IS2:
1291 		sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1292 		break;
1293 	case VCAP_TYPE_ES0:
1294 		sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
1295 		break;
1296 	case VCAP_TYPE_ES2:
1297 		sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1298 		break;
1299 	default:
1300 		sparx5_vcap_type_err(sparx5, admin, __func__);
1301 		break;
1302 	}
1303 }
1304 
1305 /* API callback used for initializing a VCAP address range */
1306 static void sparx5_vcap_range_init(struct net_device *ndev,
1307 				   struct vcap_admin *admin, u32 addr,
1308 				   u32 count)
1309 {
1310 	struct sparx5_port *port = netdev_priv(ndev);
1311 	struct sparx5 *sparx5 = port->sparx5;
1312 
1313 	_sparx5_vcap_range_init(sparx5, admin, addr, count);
1314 }
1315 
1316 static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1317 				     enum vcap_command cmd,
1318 				     enum vcap_selection sel, u32 addr)
1319 {
1320 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1321 
1322 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1323 		VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1324 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1325 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1326 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1327 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1328 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1329 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1330 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1331 		sparx5, VCAP_SUPER_CTRL);
1332 	sparx5_vcap_wait_super_update(sparx5);
1333 }
1334 
1335 static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
1336 				   enum vcap_command cmd,
1337 				   enum vcap_selection sel, u32 addr)
1338 {
1339 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1340 
1341 	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
1342 		VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
1343 	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1344 		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1345 		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1346 		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1347 		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1348 		VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
1349 		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1350 		sparx5, VCAP_ES0_CTRL);
1351 	sparx5_vcap_wait_es0_update(sparx5);
1352 }
1353 
1354 static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1355 				   enum vcap_command cmd,
1356 				   enum vcap_selection sel, u32 addr)
1357 {
1358 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1359 
1360 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1361 		VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1362 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1363 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1364 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1365 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1366 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1367 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1368 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1369 		sparx5, VCAP_ES2_CTRL);
1370 	sparx5_vcap_wait_es2_update(sparx5);
1371 }
1372 
1373 /* API callback used for updating the VCAP cache */
1374 static void sparx5_vcap_update(struct net_device *ndev,
1375 			       struct vcap_admin *admin, enum vcap_command cmd,
1376 			       enum vcap_selection sel, u32 addr)
1377 {
1378 	struct sparx5_port *port = netdev_priv(ndev);
1379 	struct sparx5 *sparx5 = port->sparx5;
1380 
1381 	switch (admin->vtype) {
1382 	case VCAP_TYPE_IS0:
1383 	case VCAP_TYPE_IS2:
1384 		sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1385 		break;
1386 	case VCAP_TYPE_ES0:
1387 		sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
1388 		break;
1389 	case VCAP_TYPE_ES2:
1390 		sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1391 		break;
1392 	default:
1393 		sparx5_vcap_type_err(sparx5, admin, __func__);
1394 		break;
1395 	}
1396 }
1397 
1398 static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1399 				   u32 addr,
1400 				   enum vcap_command cmd,
1401 				   u16 mv_num_pos,
1402 				   u16 mv_size)
1403 {
1404 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1405 		VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1406 		sparx5, VCAP_SUPER_CFG);
1407 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1408 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1409 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1410 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1411 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1412 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1413 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1414 		sparx5, VCAP_SUPER_CTRL);
1415 	sparx5_vcap_wait_super_update(sparx5);
1416 }
1417 
1418 static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
1419 				 u32 addr,
1420 				 enum vcap_command cmd,
1421 				 u16 mv_num_pos,
1422 				 u16 mv_size)
1423 {
1424 	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
1425 		VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
1426 		sparx5, VCAP_ES0_CFG);
1427 	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1428 		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1429 		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
1430 		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
1431 		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1432 		VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
1433 		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1434 		sparx5, VCAP_ES0_CTRL);
1435 	sparx5_vcap_wait_es0_update(sparx5);
1436 }
1437 
1438 static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1439 				 u32 addr,
1440 				 enum vcap_command cmd,
1441 				 u16 mv_num_pos,
1442 				 u16 mv_size)
1443 {
1444 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1445 		VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1446 		sparx5, VCAP_ES2_CFG);
1447 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1448 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1449 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1450 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1451 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1452 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1453 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1454 		sparx5, VCAP_ES2_CTRL);
1455 	sparx5_vcap_wait_es2_update(sparx5);
1456 }
1457 
1458 /* API callback used for moving a block of rules in the VCAP */
1459 static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1460 			     u32 addr, int offset, int count)
1461 {
1462 	struct sparx5_port *port = netdev_priv(ndev);
1463 	struct sparx5 *sparx5 = port->sparx5;
1464 	enum vcap_command cmd;
1465 	u16 mv_num_pos;
1466 	u16 mv_size;
1467 
1468 	mv_size = count - 1;
1469 	if (offset > 0) {
1470 		mv_num_pos = offset - 1;
1471 		cmd = VCAP_CMD_MOVE_DOWN;
1472 	} else {
1473 		mv_num_pos = -offset - 1;
1474 		cmd = VCAP_CMD_MOVE_UP;
1475 	}
1476 
1477 	switch (admin->vtype) {
1478 	case VCAP_TYPE_IS0:
1479 	case VCAP_TYPE_IS2:
1480 		sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1481 		break;
1482 	case VCAP_TYPE_ES0:
1483 		sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1484 		break;
1485 	case VCAP_TYPE_ES2:
1486 		sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1487 		break;
1488 	default:
1489 		sparx5_vcap_type_err(sparx5, admin, __func__);
1490 		break;
1491 	}
1492 }
1493 
1494 static const struct vcap_operations sparx5_vcap_ops = {
1495 	.validate_keyset = sparx5_vcap_validate_keyset,
1496 	.add_default_fields = sparx5_vcap_add_default_fields,
1497 	.cache_erase = sparx5_vcap_cache_erase,
1498 	.cache_write = sparx5_vcap_cache_write,
1499 	.cache_read = sparx5_vcap_cache_read,
1500 	.init = sparx5_vcap_range_init,
1501 	.update = sparx5_vcap_update,
1502 	.move = sparx5_vcap_move,
1503 	.port_info = sparx5_port_info,
1504 };
1505 
1506 static u32 sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)
1507 {
1508 	switch (keyset) {
1509 	case VCAP_KFS_NORMAL_7TUPLE:
1510 		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1511 	case VCAP_KFS_NORMAL_5TUPLE_IP4:
1512 		return VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4;
1513 	default:
1514 		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1515 	}
1516 }
1517 
1518 static void sparx5_vcap_is0_set_port_keyset(struct net_device *ndev, int lookup,
1519 					    enum vcap_keyfield_set keyset,
1520 					    int l3_proto)
1521 {
1522 	struct sparx5_port *port = netdev_priv(ndev);
1523 	struct sparx5 *sparx5 = port->sparx5;
1524 	int portno = port->portno;
1525 	u32 value;
1526 
1527 	switch (l3_proto) {
1528 	case ETH_P_IP:
1529 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1530 		spx5_rmw(ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(value),
1531 			 ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL,
1532 			 sparx5,
1533 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1534 		break;
1535 	case ETH_P_IPV6:
1536 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1537 		spx5_rmw(ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(value),
1538 			 ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL,
1539 			 sparx5,
1540 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1541 		break;
1542 	default:
1543 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1544 		spx5_rmw(ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(value),
1545 			 ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL,
1546 			 sparx5,
1547 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1548 		break;
1549 	}
1550 }
1551 
1552 static u32 sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1553 {
1554 	switch (keyset) {
1555 	case VCAP_KFS_ARP:
1556 		return VCAP_IS2_PS_ARP_ARP;
1557 	default:
1558 		return VCAP_IS2_PS_ARP_MAC_ETYPE;
1559 	}
1560 }
1561 
1562 static u32 sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1563 {
1564 	switch (keyset) {
1565 	case VCAP_KFS_MAC_ETYPE:
1566 		return VCAP_IS2_PS_IPV4_UC_MAC_ETYPE;
1567 	case VCAP_KFS_IP4_OTHER:
1568 	case VCAP_KFS_IP4_TCP_UDP:
1569 		return VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER;
1570 	case VCAP_KFS_IP_7TUPLE:
1571 		return VCAP_IS2_PS_IPV4_UC_IP_7TUPLE;
1572 	default:
1573 		return VCAP_KFS_NO_VALUE;
1574 	}
1575 }
1576 
1577 static u32 sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)
1578 {
1579 	switch (keyset) {
1580 	case VCAP_KFS_MAC_ETYPE:
1581 		return VCAP_IS2_PS_IPV6_UC_MAC_ETYPE;
1582 	case VCAP_KFS_IP4_OTHER:
1583 	case VCAP_KFS_IP4_TCP_UDP:
1584 		return VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER;
1585 	case VCAP_KFS_IP_7TUPLE:
1586 		return VCAP_IS2_PS_IPV6_UC_IP_7TUPLE;
1587 	default:
1588 		return VCAP_KFS_NO_VALUE;
1589 	}
1590 }
1591 
1592 static u32 sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)
1593 {
1594 	switch (keyset) {
1595 	case VCAP_KFS_MAC_ETYPE:
1596 		return VCAP_IS2_PS_IPV6_MC_MAC_ETYPE;
1597 	case VCAP_KFS_IP4_OTHER:
1598 	case VCAP_KFS_IP4_TCP_UDP:
1599 		return VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER;
1600 	case VCAP_KFS_IP_7TUPLE:
1601 		return VCAP_IS2_PS_IPV6_MC_IP_7TUPLE;
1602 	default:
1603 		return VCAP_KFS_NO_VALUE;
1604 	}
1605 }
1606 
1607 static void sparx5_vcap_is2_set_port_keyset(struct net_device *ndev, int lookup,
1608 					    enum vcap_keyfield_set keyset,
1609 					    int l3_proto)
1610 {
1611 	struct sparx5_port *port = netdev_priv(ndev);
1612 	struct sparx5 *sparx5 = port->sparx5;
1613 	int portno = port->portno;
1614 	u32 value;
1615 
1616 	switch (l3_proto) {
1617 	case ETH_P_ARP:
1618 		value = sparx5_vcap_is2_keyset_to_arp_ps(keyset);
1619 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(value),
1620 			 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL,
1621 			 sparx5,
1622 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1623 		break;
1624 	case ETH_P_IP:
1625 		value = sparx5_vcap_is2_keyset_to_ipv4_ps(keyset);
1626 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(value),
1627 			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL,
1628 			 sparx5,
1629 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1630 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(value),
1631 			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL,
1632 			 sparx5,
1633 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1634 		break;
1635 	case ETH_P_IPV6:
1636 		value = sparx5_vcap_is2_keyset_to_ipv6_uc_ps(keyset);
1637 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(value),
1638 			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL,
1639 			 sparx5,
1640 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1641 		value = sparx5_vcap_is2_keyset_to_ipv6_mc_ps(keyset);
1642 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(value),
1643 			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL,
1644 			 sparx5,
1645 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1646 		break;
1647 	default:
1648 		value = VCAP_IS2_PS_NONETH_MAC_ETYPE;
1649 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(value),
1650 			 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL,
1651 			 sparx5,
1652 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1653 		break;
1654 	}
1655 }
1656 
1657 static u32 sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1658 {
1659 	switch (keyset) {
1660 	case VCAP_KFS_ARP:
1661 		return VCAP_ES2_PS_ARP_ARP;
1662 	default:
1663 		return VCAP_ES2_PS_ARP_MAC_ETYPE;
1664 	}
1665 }
1666 
1667 static u32 sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1668 {
1669 	switch (keyset) {
1670 	case VCAP_KFS_MAC_ETYPE:
1671 		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1672 	case VCAP_KFS_IP_7TUPLE:
1673 		return VCAP_ES2_PS_IPV4_IP_7TUPLE;
1674 	case VCAP_KFS_IP4_TCP_UDP:
1675 		return VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER;
1676 	case VCAP_KFS_IP4_OTHER:
1677 		return VCAP_ES2_PS_IPV4_IP4_OTHER;
1678 	default:
1679 		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1680 	}
1681 }
1682 
1683 static u32 sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)
1684 {
1685 	switch (keyset) {
1686 	case VCAP_KFS_MAC_ETYPE:
1687 		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1688 	case VCAP_KFS_IP4_TCP_UDP:
1689 	case VCAP_KFS_IP4_OTHER:
1690 		return VCAP_ES2_PS_IPV6_IP4_DOWNGRADE;
1691 	case VCAP_KFS_IP_7TUPLE:
1692 		return VCAP_ES2_PS_IPV6_IP_7TUPLE;
1693 	case VCAP_KFS_IP6_STD:
1694 		return VCAP_ES2_PS_IPV6_IP6_STD;
1695 	default:
1696 		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1697 	}
1698 }
1699 
1700 static void sparx5_vcap_es2_set_port_keyset(struct net_device *ndev, int lookup,
1701 					    enum vcap_keyfield_set keyset,
1702 					    int l3_proto)
1703 {
1704 	struct sparx5_port *port = netdev_priv(ndev);
1705 	struct sparx5 *sparx5 = port->sparx5;
1706 	int portno = port->portno;
1707 	u32 value;
1708 
1709 	switch (l3_proto) {
1710 	case ETH_P_IP:
1711 		value = sparx5_vcap_es2_keyset_to_ipv4_ps(keyset);
1712 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(value),
1713 			 EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL,
1714 			 sparx5,
1715 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1716 		break;
1717 	case ETH_P_IPV6:
1718 		value = sparx5_vcap_es2_keyset_to_ipv6_ps(keyset);
1719 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(value),
1720 			 EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL,
1721 			 sparx5,
1722 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1723 		break;
1724 	case ETH_P_ARP:
1725 		value = sparx5_vcap_es2_keyset_to_arp_ps(keyset);
1726 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(value),
1727 			 EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL,
1728 			 sparx5,
1729 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1730 		break;
1731 	}
1732 }
1733 
1734 /* Change the port keyset for the lookup and protocol */
1735 void sparx5_vcap_set_port_keyset(struct net_device *ndev,
1736 				 struct vcap_admin *admin,
1737 				 int cid,
1738 				 u16 l3_proto,
1739 				 enum vcap_keyfield_set keyset,
1740 				 struct vcap_keyset_list *orig)
1741 {
1742 	struct sparx5_port *port;
1743 	int lookup;
1744 
1745 	switch (admin->vtype) {
1746 	case VCAP_TYPE_IS0:
1747 		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
1748 		if (orig)
1749 			sparx5_vcap_is0_get_port_keysets(ndev, lookup, orig,
1750 							 l3_proto);
1751 		sparx5_vcap_is0_set_port_keyset(ndev, lookup, keyset, l3_proto);
1752 		break;
1753 	case VCAP_TYPE_IS2:
1754 		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
1755 		if (orig)
1756 			sparx5_vcap_is2_get_port_keysets(ndev, lookup, orig,
1757 							 l3_proto);
1758 		sparx5_vcap_is2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1759 		break;
1760 	case VCAP_TYPE_ES0:
1761 		break;
1762 	case VCAP_TYPE_ES2:
1763 		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
1764 		if (orig)
1765 			sparx5_vcap_es2_get_port_keysets(ndev, lookup, orig,
1766 							 l3_proto);
1767 		sparx5_vcap_es2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1768 		break;
1769 	default:
1770 		port = netdev_priv(ndev);
1771 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
1772 		break;
1773 	}
1774 }
1775 
1776 /* Enable IS0 lookups per port and set the keyset generation */
1777 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1778 					       struct vcap_admin *admin)
1779 {
1780 	const struct sparx5_consts *consts = sparx5->data->consts;
1781 	int portno, lookup;
1782 	u32 keysel;
1783 
1784 	keysel = VCAP_IS0_KEYSEL(false,
1785 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1786 				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1787 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1788 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1789 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1790 				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1791 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1792 		for (portno = 0; portno < consts->n_ports; ++portno) {
1793 			spx5_wr(keysel, sparx5,
1794 				ANA_CL_ADV_CL_CFG(portno, lookup));
1795 			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1796 				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1797 				 sparx5,
1798 				 ANA_CL_ADV_CL_CFG(portno, lookup));
1799 		}
1800 	}
1801 }
1802 
1803 /* Enable IS2 lookups per port and set the keyset generation */
1804 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1805 					       struct vcap_admin *admin)
1806 {
1807 	const struct sparx5_consts *consts = sparx5->data->consts;
1808 	int portno, lookup;
1809 	u32 keysel;
1810 
1811 	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1812 				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1813 				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1814 				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1815 				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1816 				 VCAP_IS2_PS_ARP_ARP);
1817 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1818 		for (portno = 0; portno < consts->n_ports; ++portno) {
1819 			spx5_wr(keysel, sparx5,
1820 				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1821 		}
1822 	}
1823 	/* IS2 lookups are in bit 0:3 */
1824 	for (portno = 0; portno < consts->n_ports; ++portno)
1825 		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1826 			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1827 			 sparx5,
1828 			 ANA_ACL_VCAP_S2_CFG(portno));
1829 }
1830 
1831 /* Enable ES0 lookups per port and set the keyset generation */
1832 static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1833 					       struct vcap_admin *admin)
1834 {
1835 	const struct sparx5_consts *consts = sparx5->data->consts;
1836 	int portno;
1837 	u32 keysel;
1838 
1839 	keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1840 	for (portno = 0; portno < consts->n_ports; ++portno)
1841 		spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1842 			 sparx5, REW_RTAG_ETAG_CTRL(portno));
1843 
1844 	spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1845 		 sparx5, REW_ES0_CTRL);
1846 }
1847 
1848 /* Enable ES2 lookups per port and set the keyset generation */
1849 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1850 					       struct vcap_admin *admin)
1851 {
1852 	const struct sparx5_consts *consts = sparx5->data->consts;
1853 	int portno, lookup;
1854 	u32 keysel;
1855 
1856 	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1857 				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1858 				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1859 	for (lookup = 0; lookup < admin->lookups; ++lookup)
1860 		for (portno = 0; portno < consts->n_ports; ++portno)
1861 			spx5_wr(keysel, sparx5,
1862 				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1863 }
1864 
1865 /* Enable lookups per port and set the keyset generation */
1866 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1867 					   struct vcap_admin *admin)
1868 {
1869 	switch (admin->vtype) {
1870 	case VCAP_TYPE_IS0:
1871 		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1872 		break;
1873 	case VCAP_TYPE_IS2:
1874 		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1875 		break;
1876 	case VCAP_TYPE_ES0:
1877 		sparx5_vcap_es0_port_key_selection(sparx5, admin);
1878 		break;
1879 	case VCAP_TYPE_ES2:
1880 		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1881 		break;
1882 	default:
1883 		sparx5_vcap_type_err(sparx5, admin, __func__);
1884 		break;
1885 	}
1886 }
1887 
1888 /* Disable lookups per port */
1889 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1890 					     struct vcap_admin *admin)
1891 {
1892 	const struct sparx5_consts *consts = sparx5->data->consts;
1893 	int portno, lookup;
1894 
1895 	switch (admin->vtype) {
1896 	case VCAP_TYPE_IS0:
1897 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1898 			for (portno = 0; portno < consts->n_ports; ++portno)
1899 				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1900 					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1901 					 sparx5,
1902 					 ANA_CL_ADV_CL_CFG(portno, lookup));
1903 		break;
1904 	case VCAP_TYPE_IS2:
1905 		for (portno = 0; portno < consts->n_ports; ++portno)
1906 			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1907 				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1908 				 sparx5,
1909 				 ANA_ACL_VCAP_S2_CFG(portno));
1910 		break;
1911 	case VCAP_TYPE_ES0:
1912 		spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1913 			 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1914 		break;
1915 	case VCAP_TYPE_ES2:
1916 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1917 			for (portno = 0; portno < consts->n_ports; ++portno)
1918 				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1919 					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1920 					 sparx5,
1921 					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1922 		break;
1923 	default:
1924 		sparx5_vcap_type_err(sparx5, admin, __func__);
1925 		break;
1926 	}
1927 }
1928 
1929 static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1930 {
1931 	if (!admin)
1932 		return;
1933 	mutex_destroy(&admin->lock);
1934 	kfree(admin->cache.keystream);
1935 	kfree(admin->cache.maskstream);
1936 	kfree(admin->cache.actionstream);
1937 	kfree(admin);
1938 }
1939 
1940 /* Allocate a vcap instance with a rule list and a cache area */
1941 static struct vcap_admin *
1942 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1943 			const struct sparx5_vcap_inst *cfg)
1944 {
1945 	struct vcap_admin *admin;
1946 
1947 	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1948 	if (!admin)
1949 		return ERR_PTR(-ENOMEM);
1950 	INIT_LIST_HEAD(&admin->list);
1951 	INIT_LIST_HEAD(&admin->rules);
1952 	INIT_LIST_HEAD(&admin->enabled);
1953 	mutex_init(&admin->lock);
1954 	admin->vtype = cfg->vtype;
1955 	admin->vinst = cfg->vinst;
1956 	admin->ingress = cfg->ingress;
1957 	admin->lookups = cfg->lookups;
1958 	admin->lookups_per_instance = cfg->lookups_per_instance;
1959 	admin->first_cid = cfg->first_cid;
1960 	admin->last_cid = cfg->last_cid;
1961 	admin->cache.keystream =
1962 		kzalloc(STREAMSIZE, GFP_KERNEL);
1963 	admin->cache.maskstream =
1964 		kzalloc(STREAMSIZE, GFP_KERNEL);
1965 	admin->cache.actionstream =
1966 		kzalloc(STREAMSIZE, GFP_KERNEL);
1967 	if (!admin->cache.keystream || !admin->cache.maskstream ||
1968 	    !admin->cache.actionstream) {
1969 		sparx5_vcap_admin_free(admin);
1970 		return ERR_PTR(-ENOMEM);
1971 	}
1972 	return admin;
1973 }
1974 
1975 /* Do block allocations and provide addresses for VCAP instances */
1976 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1977 				    struct vcap_admin *admin,
1978 				    const struct sparx5_vcap_inst *cfg)
1979 {
1980 	int idx, cores;
1981 
1982 	switch (admin->vtype) {
1983 	case VCAP_TYPE_IS0:
1984 	case VCAP_TYPE_IS2:
1985 		/* Super VCAP block mapping and address configuration. Block 0
1986 		 * is assigned addresses 0 through 3071, block 1 is assigned
1987 		 * addresses 3072 though 6143, and so on.
1988 		 */
1989 		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
1990 		     ++idx) {
1991 			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
1992 				VCAP_SUPER_IDX);
1993 			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
1994 				sparx5, VCAP_SUPER_MAP);
1995 		}
1996 		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
1997 		admin->last_used_addr = admin->first_valid_addr +
1998 			cfg->blocks * SUPER_VCAP_BLK_SIZE;
1999 		admin->last_valid_addr = admin->last_used_addr - 1;
2000 		break;
2001 	case VCAP_TYPE_ES0:
2002 		admin->first_valid_addr = 0;
2003 		admin->last_used_addr = cfg->count;
2004 		admin->last_valid_addr = cfg->count - 1;
2005 		cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
2006 		for (idx = 0; idx < cores; ++idx) {
2007 			spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
2008 				VCAP_ES0_IDX);
2009 			spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
2010 				VCAP_ES0_MAP);
2011 		}
2012 		break;
2013 	case VCAP_TYPE_ES2:
2014 		admin->first_valid_addr = 0;
2015 		admin->last_used_addr = cfg->count;
2016 		admin->last_valid_addr = cfg->count - 1;
2017 		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
2018 		for (idx = 0; idx < cores; ++idx) {
2019 			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
2020 				VCAP_ES2_IDX);
2021 			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
2022 				VCAP_ES2_MAP);
2023 		}
2024 		break;
2025 	default:
2026 		sparx5_vcap_type_err(sparx5, admin, __func__);
2027 		break;
2028 	}
2029 }
2030 
2031 /* Allocate a vcap control and vcap instances and configure the system */
2032 int sparx5_vcap_init(struct sparx5 *sparx5)
2033 {
2034 	const struct sparx5_consts *consts = sparx5->data->consts;
2035 	const struct sparx5_vcap_inst *cfg;
2036 	struct vcap_control *ctrl;
2037 	struct vcap_admin *admin;
2038 	struct dentry *dir;
2039 	int err = 0, idx;
2040 
2041 	/* Create a VCAP control instance that owns the platform specific VCAP
2042 	 * model with VCAP instances and information about keysets, keys,
2043 	 * actionsets and actions
2044 	 * - Create administrative state for each available VCAP
2045 	 *   - Lists of rules
2046 	 *   - Address information
2047 	 *   - Initialize VCAP blocks
2048 	 *   - Configure port keysets
2049 	 */
2050 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
2051 	if (!ctrl)
2052 		return -ENOMEM;
2053 
2054 	sparx5->vcap_ctrl = ctrl;
2055 	/* select the sparx5 VCAP model */
2056 	ctrl->vcaps = consts->vcaps;
2057 	ctrl->stats = consts->vcap_stats;
2058 	/* Setup callbacks to allow the API to use the VCAP HW */
2059 	ctrl->ops = &sparx5_vcap_ops;
2060 
2061 	INIT_LIST_HEAD(&ctrl->list);
2062 	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
2063 		cfg = &consts->vcaps_cfg[idx];
2064 		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
2065 		if (IS_ERR(admin)) {
2066 			err = PTR_ERR(admin);
2067 			pr_err("%s:%d: vcap allocation failed: %d\n",
2068 			       __func__, __LINE__, err);
2069 			return err;
2070 		}
2071 		sparx5_vcap_block_alloc(sparx5, admin, cfg);
2072 		sparx5_vcap_block_init(sparx5, admin);
2073 		if (cfg->vinst == 0)
2074 			sparx5_vcap_port_key_selection(sparx5, admin);
2075 		list_add_tail(&admin->list, &ctrl->list);
2076 	}
2077 	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
2078 	for (idx = 0; idx < consts->n_ports; ++idx)
2079 		if (sparx5->ports[idx])
2080 			vcap_port_debugfs(sparx5->dev, dir, ctrl,
2081 					  sparx5->ports[idx]->ndev);
2082 
2083 	return err;
2084 }
2085 
2086 void sparx5_vcap_destroy(struct sparx5 *sparx5)
2087 {
2088 	struct vcap_control *ctrl = sparx5->vcap_ctrl;
2089 	struct vcap_admin *admin, *admin_next;
2090 
2091 	if (!ctrl)
2092 		return;
2093 
2094 	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
2095 		sparx5_vcap_port_key_deselection(sparx5, admin);
2096 		vcap_del_rules(ctrl, admin);
2097 		list_del(&admin->list);
2098 		sparx5_vcap_admin_free(admin);
2099 	}
2100 	kfree(ctrl);
2101 }
2102