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 SPARX5_IS2_LOOKUPS 4
21 #define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
22 	(ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
23 	 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
24 	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(_v4_mc) | \
25 	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(_v4_uc) | \
26 	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(_v6_mc) | \
27 	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
28 	 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
29 
30 #define SPARX5_IS0_LOOKUPS 6
31 #define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
32 	(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
33 	ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
34 	ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(_ipv4) | \
35 	ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(_ipv6) | \
36 	ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_SET(_mpls_uc) | \
37 	ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
38 	ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
39 
40 #define SPARX5_ES2_LOOKUPS 2
41 #define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
42 	(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
43 	EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
44 	EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
45 	EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
46 
47 static struct sparx5_vcap_inst {
48 	enum vcap_type vtype; /* type of vcap */
49 	int vinst; /* instance number within the same type */
50 	int lookups; /* number of lookups in this vcap type */
51 	int lookups_per_instance; /* number of lookups in this instance */
52 	int first_cid; /* first chain id in this vcap */
53 	int last_cid; /* last chain id in this vcap */
54 	int count; /* number of available addresses, not in super vcap */
55 	int map_id; /* id in the super vcap block mapping (if applicable) */
56 	int blockno; /* starting block in super vcap (if applicable) */
57 	int blocks; /* number of blocks in super vcap (if applicable) */
58 	bool ingress; /* is vcap in the ingress path */
59 } sparx5_vcap_inst_cfg[] = {
60 	{
61 		.vtype = VCAP_TYPE_IS0, /* CLM-0 */
62 		.vinst = 0,
63 		.map_id = 1,
64 		.lookups = SPARX5_IS0_LOOKUPS,
65 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
66 		.first_cid = SPARX5_VCAP_CID_IS0_L0,
67 		.last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
68 		.blockno = 8, /* Maps block 8-9 */
69 		.blocks = 2,
70 		.ingress = true,
71 	},
72 	{
73 		.vtype = VCAP_TYPE_IS0, /* CLM-1 */
74 		.vinst = 1,
75 		.map_id = 2,
76 		.lookups = SPARX5_IS0_LOOKUPS,
77 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
78 		.first_cid = SPARX5_VCAP_CID_IS0_L2,
79 		.last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
80 		.blockno = 6, /* Maps block 6-7 */
81 		.blocks = 2,
82 		.ingress = true,
83 	},
84 	{
85 		.vtype = VCAP_TYPE_IS0, /* CLM-2 */
86 		.vinst = 2,
87 		.map_id = 3,
88 		.lookups = SPARX5_IS0_LOOKUPS,
89 		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
90 		.first_cid = SPARX5_VCAP_CID_IS0_L4,
91 		.last_cid = SPARX5_VCAP_CID_IS0_MAX,
92 		.blockno = 4, /* Maps block 4-5 */
93 		.blocks = 2,
94 		.ingress = true,
95 	},
96 	{
97 		.vtype = VCAP_TYPE_IS2, /* IS2-0 */
98 		.vinst = 0,
99 		.map_id = 4,
100 		.lookups = SPARX5_IS2_LOOKUPS,
101 		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
102 		.first_cid = SPARX5_VCAP_CID_IS2_L0,
103 		.last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
104 		.blockno = 0, /* Maps block 0-1 */
105 		.blocks = 2,
106 		.ingress = true,
107 	},
108 	{
109 		.vtype = VCAP_TYPE_IS2, /* IS2-1 */
110 		.vinst = 1,
111 		.map_id = 5,
112 		.lookups = SPARX5_IS2_LOOKUPS,
113 		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
114 		.first_cid = SPARX5_VCAP_CID_IS2_L2,
115 		.last_cid = SPARX5_VCAP_CID_IS2_MAX,
116 		.blockno = 2, /* Maps block 2-3 */
117 		.blocks = 2,
118 		.ingress = true,
119 	},
120 	{
121 		.vtype = VCAP_TYPE_ES2,
122 		.lookups = SPARX5_ES2_LOOKUPS,
123 		.lookups_per_instance = SPARX5_ES2_LOOKUPS,
124 		.first_cid = SPARX5_VCAP_CID_ES2_L0,
125 		.last_cid = SPARX5_VCAP_CID_ES2_MAX,
126 		.count = 12288, /* Addresses according to datasheet */
127 		.ingress = false,
128 	},
129 };
130 
131 /* These protocols have dedicated keysets in IS0 and a TC dissector */
132 static u16 sparx5_vcap_is0_known_etypes[] = {
133 	ETH_P_ALL,
134 	ETH_P_IP,
135 	ETH_P_IPV6,
136 };
137 
138 /* These protocols have dedicated keysets in IS2 and a TC dissector */
139 static u16 sparx5_vcap_is2_known_etypes[] = {
140 	ETH_P_ALL,
141 	ETH_P_ARP,
142 	ETH_P_IP,
143 	ETH_P_IPV6,
144 };
145 
146 /* These protocols have dedicated keysets in ES2 and a TC dissector */
147 static u16 sparx5_vcap_es2_known_etypes[] = {
148 	ETH_P_ALL,
149 	ETH_P_ARP,
150 	ETH_P_IP,
151 	ETH_P_IPV6,
152 };
153 
154 static void sparx5_vcap_type_err(struct sparx5 *sparx5,
155 				 struct vcap_admin *admin,
156 				 const char *fname)
157 {
158 	pr_err("%s: vcap type: %s not supported\n",
159 	       fname, sparx5_vcaps[admin->vtype].name);
160 }
161 
162 /* Await the super VCAP completion of the current operation */
163 static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
164 {
165 	u32 value;
166 
167 	read_poll_timeout(spx5_rd, value,
168 			  !VCAP_SUPER_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
169 			  false, sparx5, VCAP_SUPER_CTRL);
170 }
171 
172 /* Await the ES2 VCAP completion of the current operation */
173 static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
174 {
175 	u32 value;
176 
177 	read_poll_timeout(spx5_rd, value,
178 			  !VCAP_ES2_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
179 			  false, sparx5, VCAP_ES2_CTRL);
180 }
181 
182 /* Initializing a VCAP address range */
183 static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
184 				    struct vcap_admin *admin,
185 				    u32 addr, u32 count)
186 {
187 	u32 size = count - 1;
188 
189 	switch (admin->vtype) {
190 	case VCAP_TYPE_IS0:
191 	case VCAP_TYPE_IS2:
192 		spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
193 			VCAP_SUPER_CFG_MV_SIZE_SET(size),
194 			sparx5, VCAP_SUPER_CFG);
195 		spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
196 			VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
197 			VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
198 			VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
199 			VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
200 			VCAP_SUPER_CTRL_CLEAR_CACHE_SET(true) |
201 			VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
202 			sparx5, VCAP_SUPER_CTRL);
203 		sparx5_vcap_wait_super_update(sparx5);
204 		break;
205 	case VCAP_TYPE_ES2:
206 		spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
207 			VCAP_ES2_CFG_MV_SIZE_SET(size),
208 			sparx5, VCAP_ES2_CFG);
209 		spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
210 			VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
211 			VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
212 			VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
213 			VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
214 			VCAP_ES2_CTRL_CLEAR_CACHE_SET(true) |
215 			VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
216 			sparx5, VCAP_ES2_CTRL);
217 		sparx5_vcap_wait_es2_update(sparx5);
218 		break;
219 	default:
220 		sparx5_vcap_type_err(sparx5, admin, __func__);
221 		break;
222 	}
223 }
224 
225 /* Initializing VCAP rule data area */
226 static void sparx5_vcap_block_init(struct sparx5 *sparx5,
227 				   struct vcap_admin *admin)
228 {
229 	_sparx5_vcap_range_init(sparx5, admin, admin->first_valid_addr,
230 				admin->last_valid_addr -
231 					admin->first_valid_addr);
232 }
233 
234 /* Get the keyset name from the sparx5 VCAP model */
235 static const char *sparx5_vcap_keyset_name(struct net_device *ndev,
236 					   enum vcap_keyfield_set keyset)
237 {
238 	struct sparx5_port *port = netdev_priv(ndev);
239 
240 	return vcap_keyset_name(port->sparx5->vcap_ctrl, keyset);
241 }
242 
243 /* Check if this is the first lookup of IS0 */
244 static bool sparx5_vcap_is0_is_first_chain(struct vcap_rule *rule)
245 {
246 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L0 &&
247 		rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L1) ||
248 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L2 &&
249 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L3)) ||
250 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L4 &&
251 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L5));
252 }
253 
254 /* Check if this is the first lookup of IS2 */
255 static bool sparx5_vcap_is2_is_first_chain(struct vcap_rule *rule)
256 {
257 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L0 &&
258 		rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L1) ||
259 		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L2 &&
260 		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L3));
261 }
262 
263 static bool sparx5_vcap_es2_is_first_chain(struct vcap_rule *rule)
264 {
265 	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_ES2_L0 &&
266 		rule->vcap_chain_id < SPARX5_VCAP_CID_ES2_L1);
267 }
268 
269 /* Set the narrow range ingress port mask on a rule */
270 static void sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule *rule,
271 						    struct net_device *ndev)
272 {
273 	struct sparx5_port *port = netdev_priv(ndev);
274 	u32 port_mask;
275 	u32 range;
276 
277 	range = port->portno / BITS_PER_TYPE(u32);
278 	/* Port bit set to match-any */
279 	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
280 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_SEL, 0, 0xf);
281 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, range, 0xf);
282 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, port_mask);
283 }
284 
285 /* Set the wide range ingress port mask on a rule */
286 static void sparx5_vcap_add_wide_port_mask(struct vcap_rule *rule,
287 					   struct net_device *ndev)
288 {
289 	struct sparx5_port *port = netdev_priv(ndev);
290 	struct vcap_u72_key port_mask;
291 	u32 range;
292 
293 	/* Port bit set to match-any */
294 	memset(port_mask.value, 0, sizeof(port_mask.value));
295 	memset(port_mask.mask, 0xff, sizeof(port_mask.mask));
296 	range = port->portno / BITS_PER_BYTE;
297 	port_mask.mask[range] = ~BIT(port->portno % BITS_PER_BYTE);
298 	vcap_rule_add_key_u72(rule, VCAP_KF_IF_IGR_PORT_MASK, &port_mask);
299 }
300 
301 static void sparx5_vcap_add_egress_range_port_mask(struct vcap_rule *rule,
302 						   struct net_device *ndev)
303 {
304 	struct sparx5_port *port = netdev_priv(ndev);
305 	u32 port_mask;
306 	u32 range;
307 
308 	/* Mask range selects:
309 	 * 0-2: Physical/Logical egress port number 0-31, 32–63, 64.
310 	 * 3-5: Virtual Interface Number 0-31, 32-63, 64.
311 	 * 6: CPU queue Number 0-7.
312 	 *
313 	 * Use physical/logical port ranges (0-2)
314 	 */
315 	range = port->portno / BITS_PER_TYPE(u32);
316 	/* Port bit set to match-any */
317 	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
318 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK_RNG, range, 0xf);
319 	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK, 0, port_mask);
320 }
321 
322 /* Convert IS0 chain id to vcap lookup id */
323 static int sparx5_vcap_is0_cid_to_lookup(int cid)
324 {
325 	int lookup = 0;
326 
327 	if (cid >= SPARX5_VCAP_CID_IS0_L1 && cid < SPARX5_VCAP_CID_IS0_L2)
328 		lookup = 1;
329 	else if (cid >= SPARX5_VCAP_CID_IS0_L2 && cid < SPARX5_VCAP_CID_IS0_L3)
330 		lookup = 2;
331 	else if (cid >= SPARX5_VCAP_CID_IS0_L3 && cid < SPARX5_VCAP_CID_IS0_L4)
332 		lookup = 3;
333 	else if (cid >= SPARX5_VCAP_CID_IS0_L4 && cid < SPARX5_VCAP_CID_IS0_L5)
334 		lookup = 4;
335 	else if (cid >= SPARX5_VCAP_CID_IS0_L5 && cid < SPARX5_VCAP_CID_IS0_MAX)
336 		lookup = 5;
337 
338 	return lookup;
339 }
340 
341 /* Convert IS2 chain id to vcap lookup id */
342 static int sparx5_vcap_is2_cid_to_lookup(int cid)
343 {
344 	int lookup = 0;
345 
346 	if (cid >= SPARX5_VCAP_CID_IS2_L1 && cid < SPARX5_VCAP_CID_IS2_L2)
347 		lookup = 1;
348 	else if (cid >= SPARX5_VCAP_CID_IS2_L2 && cid < SPARX5_VCAP_CID_IS2_L3)
349 		lookup = 2;
350 	else if (cid >= SPARX5_VCAP_CID_IS2_L3 && cid < SPARX5_VCAP_CID_IS2_MAX)
351 		lookup = 3;
352 
353 	return lookup;
354 }
355 
356 /* Convert ES2 chain id to vcap lookup id */
357 static int sparx5_vcap_es2_cid_to_lookup(int cid)
358 {
359 	int lookup = 0;
360 
361 	if (cid >= SPARX5_VCAP_CID_ES2_L1)
362 		lookup = 1;
363 
364 	return lookup;
365 }
366 
367 /* Add ethernet type IS0 keyset to a list */
368 static void
369 sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list *keysetlist,
370 				       u32 value)
371 {
372 	switch (ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value)) {
373 	case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
374 		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_7TUPLE);
375 		break;
376 	case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
377 		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_5TUPLE_IP4);
378 		break;
379 	}
380 }
381 
382 /* Return the list of keysets for the vcap port configuration */
383 static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
384 					    int lookup,
385 					    struct vcap_keyset_list *keysetlist,
386 					    u16 l3_proto)
387 {
388 	struct sparx5_port *port = netdev_priv(ndev);
389 	struct sparx5 *sparx5 = port->sparx5;
390 	int portno = port->portno;
391 	u32 value;
392 
393 	value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
394 
395 	/* Collect all keysets for the port in a list */
396 	if (l3_proto == ETH_P_ALL)
397 		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
398 
399 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
400 		switch (ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value)) {
401 		case VCAP_IS0_PS_ETYPE_DEFAULT:
402 			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
403 							       value);
404 			break;
405 		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
406 			vcap_keyset_list_add(keysetlist,
407 					     VCAP_KFS_NORMAL_7TUPLE);
408 			break;
409 		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
410 			vcap_keyset_list_add(keysetlist,
411 					     VCAP_KFS_NORMAL_5TUPLE_IP4);
412 			break;
413 		}
414 
415 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6)
416 		switch (ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value)) {
417 		case VCAP_IS0_PS_ETYPE_DEFAULT:
418 			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
419 							       value);
420 			break;
421 		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
422 			vcap_keyset_list_add(keysetlist,
423 					     VCAP_KFS_NORMAL_7TUPLE);
424 			break;
425 		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
426 			vcap_keyset_list_add(keysetlist,
427 					     VCAP_KFS_NORMAL_5TUPLE_IP4);
428 			break;
429 		}
430 
431 	if (l3_proto != ETH_P_IP && l3_proto != ETH_P_IPV6)
432 		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
433 	return 0;
434 }
435 
436 /* Return the list of keysets for the vcap port configuration */
437 static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
438 					    int lookup,
439 					    struct vcap_keyset_list *keysetlist,
440 					    u16 l3_proto)
441 {
442 	struct sparx5_port *port = netdev_priv(ndev);
443 	struct sparx5 *sparx5 = port->sparx5;
444 	int portno = port->portno;
445 	u32 value;
446 
447 	value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
448 
449 	/* Collect all keysets for the port in a list */
450 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
451 		switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
452 		case VCAP_IS2_PS_ARP_MAC_ETYPE:
453 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
454 			break;
455 		case VCAP_IS2_PS_ARP_ARP:
456 			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
457 			break;
458 		}
459 	}
460 
461 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
462 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
463 		case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
464 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
465 			break;
466 		case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
467 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
468 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
469 			break;
470 		case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
471 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
472 			break;
473 		}
474 
475 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
476 		case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
477 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
478 			break;
479 		case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
480 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
481 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
482 			break;
483 		case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
484 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
485 			break;
486 		}
487 	}
488 
489 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
490 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
491 		case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
492 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
493 			break;
494 		case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
495 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
496 			break;
497 		case VCAP_IS2_PS_IPV6_UC_IP6_STD:
498 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
499 			break;
500 		case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
501 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
502 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
503 			break;
504 		}
505 
506 		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
507 		case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
508 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
509 			break;
510 		case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
511 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
512 			break;
513 		case VCAP_IS2_PS_IPV6_MC_IP6_STD:
514 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
515 			break;
516 		case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
517 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
518 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
519 			break;
520 		case VCAP_IS2_PS_IPV6_MC_IP6_VID:
521 			/* Not used */
522 			break;
523 		}
524 	}
525 
526 	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
527 	    l3_proto != ETH_P_IPV6) {
528 		switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
529 		case VCAP_IS2_PS_NONETH_MAC_ETYPE:
530 			/* IS2 non-classified frames generate MAC_ETYPE */
531 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
532 			break;
533 		}
534 	}
535 	return 0;
536 }
537 
538 /* Return the keysets for the vcap port IP4 traffic class configuration */
539 static void
540 sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
541 				      u32 value)
542 {
543 	switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
544 	case VCAP_ES2_PS_IPV4_MAC_ETYPE:
545 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
546 		break;
547 	case VCAP_ES2_PS_IPV4_IP_7TUPLE:
548 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
549 		break;
550 	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
551 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
552 		break;
553 	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
554 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
555 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
556 		break;
557 	case VCAP_ES2_PS_IPV4_IP4_VID:
558 		/* Not used */
559 		break;
560 	case VCAP_ES2_PS_IPV4_IP4_OTHER:
561 		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
562 		break;
563 	}
564 }
565 
566 /* Return the list of keysets for the vcap port configuration */
567 static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
568 					    int lookup,
569 					    struct vcap_keyset_list *keysetlist,
570 					    u16 l3_proto)
571 {
572 	struct sparx5_port *port = netdev_priv(ndev);
573 	struct sparx5 *sparx5 = port->sparx5;
574 	int portno = port->portno;
575 	u32 value;
576 
577 	value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(portno, lookup));
578 
579 	/* Collect all keysets for the port in a list */
580 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
581 		switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
582 		case VCAP_ES2_PS_ARP_MAC_ETYPE:
583 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
584 			break;
585 		case VCAP_ES2_PS_ARP_ARP:
586 			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
587 			break;
588 		}
589 	}
590 
591 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
592 		sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist, value);
593 
594 	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
595 		switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
596 		case VCAP_ES2_PS_IPV6_MAC_ETYPE:
597 			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
598 			break;
599 		case VCAP_ES2_PS_IPV6_IP_7TUPLE:
600 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
601 			break;
602 		case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
603 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
604 			break;
605 		case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
606 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
607 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
608 			break;
609 		case VCAP_ES2_PS_IPV6_IP6_VID:
610 			/* Not used */
611 			break;
612 		case VCAP_ES2_PS_IPV6_IP6_STD:
613 			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
614 			break;
615 		case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
616 			sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist,
617 							      value);
618 			break;
619 		}
620 	}
621 
622 	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
623 	    l3_proto != ETH_P_IPV6) {
624 		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
625 	}
626 	return 0;
627 }
628 
629 /* Get the port keyset for the vcap lookup */
630 int sparx5_vcap_get_port_keyset(struct net_device *ndev,
631 				struct vcap_admin *admin,
632 				int cid,
633 				u16 l3_proto,
634 				struct vcap_keyset_list *kslist)
635 {
636 	int lookup, err = -EINVAL;
637 	struct sparx5_port *port;
638 
639 	switch (admin->vtype) {
640 	case VCAP_TYPE_IS0:
641 		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
642 		err = sparx5_vcap_is0_get_port_keysets(ndev, lookup, kslist,
643 						       l3_proto);
644 		break;
645 	case VCAP_TYPE_IS2:
646 		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
647 		err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
648 						       l3_proto);
649 		break;
650 	case VCAP_TYPE_ES2:
651 		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
652 		err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
653 						       l3_proto);
654 		break;
655 	default:
656 		port = netdev_priv(ndev);
657 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
658 		break;
659 	}
660 	return err;
661 }
662 
663 /* Check if the ethertype is supported by the vcap port classification */
664 bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
665 {
666 	const u16 *known_etypes;
667 	int size, idx;
668 
669 	switch (admin->vtype) {
670 	case VCAP_TYPE_IS0:
671 		known_etypes = sparx5_vcap_is0_known_etypes;
672 		size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
673 		break;
674 	case VCAP_TYPE_IS2:
675 		known_etypes = sparx5_vcap_is2_known_etypes;
676 		size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
677 		break;
678 	case VCAP_TYPE_ES2:
679 		known_etypes = sparx5_vcap_es2_known_etypes;
680 		size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
681 		break;
682 	default:
683 		return false;
684 	}
685 	for (idx = 0; idx < size; ++idx)
686 		if (known_etypes[idx] == etype)
687 			return true;
688 	return false;
689 }
690 
691 /* API callback used for validating a field keyset (check the port keysets) */
692 static enum vcap_keyfield_set
693 sparx5_vcap_validate_keyset(struct net_device *ndev,
694 			    struct vcap_admin *admin,
695 			    struct vcap_rule *rule,
696 			    struct vcap_keyset_list *kslist,
697 			    u16 l3_proto)
698 {
699 	struct vcap_keyset_list keysetlist = {};
700 	enum vcap_keyfield_set keysets[10] = {};
701 	struct sparx5_port *port;
702 	int idx, jdx, lookup;
703 
704 	if (!kslist || kslist->cnt == 0)
705 		return VCAP_KFS_NO_VALUE;
706 
707 	keysetlist.max = ARRAY_SIZE(keysets);
708 	keysetlist.keysets = keysets;
709 
710 	/* Get a list of currently configured keysets in the lookups */
711 	switch (admin->vtype) {
712 	case VCAP_TYPE_IS0:
713 		lookup = sparx5_vcap_is0_cid_to_lookup(rule->vcap_chain_id);
714 		sparx5_vcap_is0_get_port_keysets(ndev, lookup, &keysetlist,
715 						 l3_proto);
716 		break;
717 	case VCAP_TYPE_IS2:
718 		lookup = sparx5_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
719 		sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
720 						 l3_proto);
721 		break;
722 	case VCAP_TYPE_ES2:
723 		lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
724 		sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
725 						 l3_proto);
726 		break;
727 	default:
728 		port = netdev_priv(ndev);
729 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
730 		break;
731 	}
732 
733 	/* Check if there is a match and return the match */
734 	for (idx = 0; idx < kslist->cnt; ++idx)
735 		for (jdx = 0; jdx < keysetlist.cnt; ++jdx)
736 			if (kslist->keysets[idx] == keysets[jdx])
737 				return kslist->keysets[idx];
738 
739 	pr_err("%s:%d: %s not supported in port key selection\n",
740 	       __func__, __LINE__,
741 	       sparx5_vcap_keyset_name(ndev, kslist->keysets[0]));
742 
743 	return -ENOENT;
744 }
745 
746 static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
747 						   struct vcap_admin *admin,
748 						   struct vcap_rule *rule)
749 {
750 	const struct vcap_field *field;
751 	bool is_first;
752 
753 	/* Add ingress port mask matching the net device */
754 	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_IGR_PORT_MASK);
755 	if (field && field->width == SPX5_PORTS)
756 		sparx5_vcap_add_wide_port_mask(rule, ndev);
757 	else if (field && field->width == BITS_PER_TYPE(u32))
758 		sparx5_vcap_add_ingress_range_port_mask(rule, ndev);
759 	else
760 		pr_err("%s:%d: %s: could not add an ingress port mask for: %s\n",
761 		       __func__, __LINE__, netdev_name(ndev),
762 		       sparx5_vcap_keyset_name(ndev, rule->keyset));
763 
764 	if (admin->vtype == VCAP_TYPE_IS0)
765 		is_first = sparx5_vcap_is0_is_first_chain(rule);
766 	else
767 		is_first = sparx5_vcap_is2_is_first_chain(rule);
768 
769 	/* Add key that selects the first/second lookup */
770 	if (is_first)
771 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
772 				      VCAP_BIT_1);
773 	else
774 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
775 				      VCAP_BIT_0);
776 }
777 
778 static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
779 					       struct vcap_admin *admin,
780 					       struct vcap_rule *rule)
781 {
782 	const struct vcap_field *field;
783 	bool is_first;
784 
785 	/* Add egress port mask matching the net device */
786 	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
787 	if (field)
788 		sparx5_vcap_add_egress_range_port_mask(rule, ndev);
789 
790 	/* Add key that selects the first/second lookup */
791 	is_first = sparx5_vcap_es2_is_first_chain(rule);
792 
793 	if (is_first)
794 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
795 				      VCAP_BIT_1);
796 	else
797 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
798 				      VCAP_BIT_0);
799 }
800 
801 /* API callback used for adding default fields to a rule */
802 static void sparx5_vcap_add_default_fields(struct net_device *ndev,
803 					   struct vcap_admin *admin,
804 					   struct vcap_rule *rule)
805 {
806 	struct sparx5_port *port;
807 
808 	/* add the lookup bit */
809 	switch (admin->vtype) {
810 	case VCAP_TYPE_IS0:
811 	case VCAP_TYPE_IS2:
812 		sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
813 		break;
814 	case VCAP_TYPE_ES2:
815 		sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
816 		break;
817 	default:
818 		port = netdev_priv(ndev);
819 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
820 		break;
821 	}
822 }
823 
824 /* API callback used for erasing the vcap cache area (not the register area) */
825 static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
826 {
827 	memset(admin->cache.keystream, 0, STREAMSIZE);
828 	memset(admin->cache.maskstream, 0, STREAMSIZE);
829 	memset(admin->cache.actionstream, 0, STREAMSIZE);
830 	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
831 }
832 
833 static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
834 					struct vcap_admin *admin,
835 					enum vcap_selection sel,
836 					u32 start,
837 					u32 count)
838 {
839 	u32 *keystr, *mskstr, *actstr;
840 	int idx;
841 
842 	keystr = &admin->cache.keystream[start];
843 	mskstr = &admin->cache.maskstream[start];
844 	actstr = &admin->cache.actionstream[start];
845 
846 	switch (sel) {
847 	case VCAP_SEL_ENTRY:
848 		for (idx = 0; idx < count; ++idx) {
849 			/* Avoid 'match-off' by setting value & mask */
850 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
851 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
852 			spx5_wr(~mskstr[idx], sparx5,
853 				VCAP_SUPER_VCAP_MASK_DAT(idx));
854 		}
855 		break;
856 	case VCAP_SEL_ACTION:
857 		for (idx = 0; idx < count; ++idx)
858 			spx5_wr(actstr[idx], sparx5,
859 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
860 		break;
861 	case VCAP_SEL_ALL:
862 		pr_err("%s:%d: cannot write all streams at once\n",
863 		       __func__, __LINE__);
864 		break;
865 	default:
866 		break;
867 	}
868 
869 	if (sel & VCAP_SEL_COUNTER)
870 		spx5_wr(admin->cache.counter, sparx5,
871 			VCAP_SUPER_VCAP_CNT_DAT(0));
872 }
873 
874 static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
875 					struct vcap_admin *admin,
876 					enum vcap_selection sel,
877 					u32 start,
878 					u32 count)
879 {
880 	u32 *keystr, *mskstr, *actstr;
881 	int idx;
882 
883 	keystr = &admin->cache.keystream[start];
884 	mskstr = &admin->cache.maskstream[start];
885 	actstr = &admin->cache.actionstream[start];
886 
887 	switch (sel) {
888 	case VCAP_SEL_ENTRY:
889 		for (idx = 0; idx < count; ++idx) {
890 			/* Avoid 'match-off' by setting value & mask */
891 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
892 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
893 			spx5_wr(~mskstr[idx], sparx5,
894 				VCAP_SUPER_VCAP_MASK_DAT(idx));
895 		}
896 		break;
897 	case VCAP_SEL_ACTION:
898 		for (idx = 0; idx < count; ++idx)
899 			spx5_wr(actstr[idx], sparx5,
900 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
901 		break;
902 	case VCAP_SEL_ALL:
903 		pr_err("%s:%d: cannot write all streams at once\n",
904 		       __func__, __LINE__);
905 		break;
906 	default:
907 		break;
908 	}
909 	if (sel & VCAP_SEL_COUNTER) {
910 		start = start & 0xfff; /* counter limit */
911 		if (admin->vinst == 0)
912 			spx5_wr(admin->cache.counter, sparx5,
913 				ANA_ACL_CNT_A(start));
914 		else
915 			spx5_wr(admin->cache.counter, sparx5,
916 				ANA_ACL_CNT_B(start));
917 		spx5_wr(admin->cache.sticky, sparx5,
918 			VCAP_SUPER_VCAP_CNT_DAT(0));
919 	}
920 }
921 
922 static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
923 					struct vcap_admin *admin,
924 					enum vcap_selection sel,
925 					u32 start,
926 					u32 count)
927 {
928 	u32 *keystr, *mskstr, *actstr;
929 	int idx;
930 
931 	keystr = &admin->cache.keystream[start];
932 	mskstr = &admin->cache.maskstream[start];
933 	actstr = &admin->cache.actionstream[start];
934 
935 	switch (sel) {
936 	case VCAP_SEL_ENTRY:
937 		for (idx = 0; idx < count; ++idx) {
938 			/* Avoid 'match-off' by setting value & mask */
939 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
940 				VCAP_ES2_VCAP_ENTRY_DAT(idx));
941 			spx5_wr(~mskstr[idx], sparx5,
942 				VCAP_ES2_VCAP_MASK_DAT(idx));
943 		}
944 		break;
945 	case VCAP_SEL_ACTION:
946 		for (idx = 0; idx < count; ++idx)
947 			spx5_wr(actstr[idx], sparx5,
948 				VCAP_ES2_VCAP_ACTION_DAT(idx));
949 		break;
950 	case VCAP_SEL_ALL:
951 		pr_err("%s:%d: cannot write all streams at once\n",
952 		       __func__, __LINE__);
953 		break;
954 	default:
955 		break;
956 	}
957 	if (sel & VCAP_SEL_COUNTER) {
958 		start = start & 0x7ff; /* counter limit */
959 		spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
960 		spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
961 	}
962 }
963 
964 /* API callback used for writing to the VCAP cache */
965 static void sparx5_vcap_cache_write(struct net_device *ndev,
966 				    struct vcap_admin *admin,
967 				    enum vcap_selection sel,
968 				    u32 start,
969 				    u32 count)
970 {
971 	struct sparx5_port *port = netdev_priv(ndev);
972 	struct sparx5 *sparx5 = port->sparx5;
973 
974 	switch (admin->vtype) {
975 	case VCAP_TYPE_IS0:
976 		sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
977 		break;
978 	case VCAP_TYPE_IS2:
979 		sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
980 		break;
981 	case VCAP_TYPE_ES2:
982 		sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
983 		break;
984 	default:
985 		sparx5_vcap_type_err(sparx5, admin, __func__);
986 		break;
987 	}
988 }
989 
990 static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
991 				       struct vcap_admin *admin,
992 				       enum vcap_selection sel,
993 				       u32 start,
994 				       u32 count)
995 {
996 	u32 *keystr, *mskstr, *actstr;
997 	int idx;
998 
999 	keystr = &admin->cache.keystream[start];
1000 	mskstr = &admin->cache.maskstream[start];
1001 	actstr = &admin->cache.actionstream[start];
1002 
1003 	if (sel & VCAP_SEL_ENTRY) {
1004 		for (idx = 0; idx < count; ++idx) {
1005 			keystr[idx] = spx5_rd(sparx5,
1006 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1007 			mskstr[idx] = ~spx5_rd(sparx5,
1008 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1009 		}
1010 	}
1011 
1012 	if (sel & VCAP_SEL_ACTION)
1013 		for (idx = 0; idx < count; ++idx)
1014 			actstr[idx] = spx5_rd(sparx5,
1015 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1016 
1017 	if (sel & VCAP_SEL_COUNTER) {
1018 		admin->cache.counter =
1019 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1020 		admin->cache.sticky =
1021 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1022 	}
1023 }
1024 
1025 static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1026 				       struct vcap_admin *admin,
1027 				       enum vcap_selection sel,
1028 				       u32 start,
1029 				       u32 count)
1030 {
1031 	u32 *keystr, *mskstr, *actstr;
1032 	int idx;
1033 
1034 	keystr = &admin->cache.keystream[start];
1035 	mskstr = &admin->cache.maskstream[start];
1036 	actstr = &admin->cache.actionstream[start];
1037 
1038 	if (sel & VCAP_SEL_ENTRY) {
1039 		for (idx = 0; idx < count; ++idx) {
1040 			keystr[idx] = spx5_rd(sparx5,
1041 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1042 			mskstr[idx] = ~spx5_rd(sparx5,
1043 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1044 		}
1045 	}
1046 
1047 	if (sel & VCAP_SEL_ACTION)
1048 		for (idx = 0; idx < count; ++idx)
1049 			actstr[idx] = spx5_rd(sparx5,
1050 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1051 
1052 	if (sel & VCAP_SEL_COUNTER) {
1053 		start = start & 0xfff; /* counter limit */
1054 		if (admin->vinst == 0)
1055 			admin->cache.counter =
1056 				spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1057 		else
1058 			admin->cache.counter =
1059 				spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1060 		admin->cache.sticky =
1061 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1062 	}
1063 }
1064 
1065 static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1066 				       struct vcap_admin *admin,
1067 				       enum vcap_selection sel,
1068 				       u32 start,
1069 				       u32 count)
1070 {
1071 	u32 *keystr, *mskstr, *actstr;
1072 	int idx;
1073 
1074 	keystr = &admin->cache.keystream[start];
1075 	mskstr = &admin->cache.maskstream[start];
1076 	actstr = &admin->cache.actionstream[start];
1077 
1078 	if (sel & VCAP_SEL_ENTRY) {
1079 		for (idx = 0; idx < count; ++idx) {
1080 			keystr[idx] =
1081 				spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1082 			mskstr[idx] =
1083 				~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1084 		}
1085 	}
1086 
1087 	if (sel & VCAP_SEL_ACTION)
1088 		for (idx = 0; idx < count; ++idx)
1089 			actstr[idx] =
1090 				spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1091 
1092 	if (sel & VCAP_SEL_COUNTER) {
1093 		start = start & 0x7ff; /* counter limit */
1094 		admin->cache.counter =
1095 			spx5_rd(sparx5, EACL_ES2_CNT(start));
1096 		admin->cache.sticky =
1097 			spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1098 	}
1099 }
1100 
1101 /* API callback used for reading from the VCAP into the VCAP cache */
1102 static void sparx5_vcap_cache_read(struct net_device *ndev,
1103 				   struct vcap_admin *admin,
1104 				   enum vcap_selection sel,
1105 				   u32 start,
1106 				   u32 count)
1107 {
1108 	struct sparx5_port *port = netdev_priv(ndev);
1109 	struct sparx5 *sparx5 = port->sparx5;
1110 
1111 	switch (admin->vtype) {
1112 	case VCAP_TYPE_IS0:
1113 		sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1114 		break;
1115 	case VCAP_TYPE_IS2:
1116 		sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1117 		break;
1118 	case VCAP_TYPE_ES2:
1119 		sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1120 		break;
1121 	default:
1122 		sparx5_vcap_type_err(sparx5, admin, __func__);
1123 		break;
1124 	}
1125 }
1126 
1127 /* API callback used for initializing a VCAP address range */
1128 static void sparx5_vcap_range_init(struct net_device *ndev,
1129 				   struct vcap_admin *admin, u32 addr,
1130 				   u32 count)
1131 {
1132 	struct sparx5_port *port = netdev_priv(ndev);
1133 	struct sparx5 *sparx5 = port->sparx5;
1134 
1135 	_sparx5_vcap_range_init(sparx5, admin, addr, count);
1136 }
1137 
1138 static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1139 				     enum vcap_command cmd,
1140 				     enum vcap_selection sel, u32 addr)
1141 {
1142 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1143 
1144 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1145 		VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1146 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1147 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1148 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1149 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1150 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1151 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1152 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1153 		sparx5, VCAP_SUPER_CTRL);
1154 	sparx5_vcap_wait_super_update(sparx5);
1155 }
1156 
1157 static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1158 				   enum vcap_command cmd,
1159 				   enum vcap_selection sel, u32 addr)
1160 {
1161 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1162 
1163 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1164 		VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1165 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1166 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1167 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1168 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1169 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1170 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1171 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1172 		sparx5, VCAP_ES2_CTRL);
1173 	sparx5_vcap_wait_es2_update(sparx5);
1174 }
1175 
1176 /* API callback used for updating the VCAP cache */
1177 static void sparx5_vcap_update(struct net_device *ndev,
1178 			       struct vcap_admin *admin, enum vcap_command cmd,
1179 			       enum vcap_selection sel, u32 addr)
1180 {
1181 	struct sparx5_port *port = netdev_priv(ndev);
1182 	struct sparx5 *sparx5 = port->sparx5;
1183 
1184 	switch (admin->vtype) {
1185 	case VCAP_TYPE_IS0:
1186 	case VCAP_TYPE_IS2:
1187 		sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1188 		break;
1189 	case VCAP_TYPE_ES2:
1190 		sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1191 		break;
1192 	default:
1193 		sparx5_vcap_type_err(sparx5, admin, __func__);
1194 		break;
1195 	}
1196 }
1197 
1198 static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1199 				   u32 addr,
1200 				   enum vcap_command cmd,
1201 				   u16 mv_num_pos,
1202 				   u16 mv_size)
1203 {
1204 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1205 		VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1206 		sparx5, VCAP_SUPER_CFG);
1207 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1208 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1209 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1210 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1211 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1212 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1213 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1214 		sparx5, VCAP_SUPER_CTRL);
1215 	sparx5_vcap_wait_super_update(sparx5);
1216 }
1217 
1218 static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1219 				 u32 addr,
1220 				 enum vcap_command cmd,
1221 				 u16 mv_num_pos,
1222 				 u16 mv_size)
1223 {
1224 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1225 		VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1226 		sparx5, VCAP_ES2_CFG);
1227 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1228 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1229 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1230 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1231 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1232 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1233 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1234 		sparx5, VCAP_ES2_CTRL);
1235 	sparx5_vcap_wait_es2_update(sparx5);
1236 }
1237 
1238 /* API callback used for moving a block of rules in the VCAP */
1239 static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1240 			     u32 addr, int offset, int count)
1241 {
1242 	struct sparx5_port *port = netdev_priv(ndev);
1243 	struct sparx5 *sparx5 = port->sparx5;
1244 	enum vcap_command cmd;
1245 	u16 mv_num_pos;
1246 	u16 mv_size;
1247 
1248 	mv_size = count - 1;
1249 	if (offset > 0) {
1250 		mv_num_pos = offset - 1;
1251 		cmd = VCAP_CMD_MOVE_DOWN;
1252 	} else {
1253 		mv_num_pos = -offset - 1;
1254 		cmd = VCAP_CMD_MOVE_UP;
1255 	}
1256 
1257 	switch (admin->vtype) {
1258 	case VCAP_TYPE_IS0:
1259 	case VCAP_TYPE_IS2:
1260 		sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1261 		break;
1262 	case VCAP_TYPE_ES2:
1263 		sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1264 		break;
1265 	default:
1266 		sparx5_vcap_type_err(sparx5, admin, __func__);
1267 		break;
1268 	}
1269 }
1270 
1271 static struct vcap_operations sparx5_vcap_ops = {
1272 	.validate_keyset = sparx5_vcap_validate_keyset,
1273 	.add_default_fields = sparx5_vcap_add_default_fields,
1274 	.cache_erase = sparx5_vcap_cache_erase,
1275 	.cache_write = sparx5_vcap_cache_write,
1276 	.cache_read = sparx5_vcap_cache_read,
1277 	.init = sparx5_vcap_range_init,
1278 	.update = sparx5_vcap_update,
1279 	.move = sparx5_vcap_move,
1280 	.port_info = sparx5_port_info,
1281 };
1282 
1283 /* Enable IS0 lookups per port and set the keyset generation */
1284 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1285 					       struct vcap_admin *admin)
1286 {
1287 	int portno, lookup;
1288 	u32 keysel;
1289 
1290 	keysel = VCAP_IS0_KEYSEL(false,
1291 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1292 				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1293 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1294 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1295 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1296 				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1297 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1298 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1299 			spx5_wr(keysel, sparx5,
1300 				ANA_CL_ADV_CL_CFG(portno, lookup));
1301 			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1302 				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1303 				 sparx5,
1304 				 ANA_CL_ADV_CL_CFG(portno, lookup));
1305 		}
1306 	}
1307 }
1308 
1309 /* Enable IS2 lookups per port and set the keyset generation */
1310 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1311 					       struct vcap_admin *admin)
1312 {
1313 	int portno, lookup;
1314 	u32 keysel;
1315 
1316 	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1317 				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1318 				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1319 				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1320 				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1321 				 VCAP_IS2_PS_ARP_ARP);
1322 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1323 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1324 			spx5_wr(keysel, sparx5,
1325 				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1326 		}
1327 	}
1328 	/* IS2 lookups are in bit 0:3 */
1329 	for (portno = 0; portno < SPX5_PORTS; ++portno)
1330 		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1331 			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1332 			 sparx5,
1333 			 ANA_ACL_VCAP_S2_CFG(portno));
1334 }
1335 
1336 /* Enable ES2 lookups per port and set the keyset generation */
1337 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1338 					       struct vcap_admin *admin)
1339 {
1340 	int portno, lookup;
1341 	u32 keysel;
1342 
1343 	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1344 				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1345 				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1346 	for (lookup = 0; lookup < admin->lookups; ++lookup)
1347 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1348 			spx5_wr(keysel, sparx5,
1349 				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1350 }
1351 
1352 /* Enable lookups per port and set the keyset generation */
1353 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1354 					   struct vcap_admin *admin)
1355 {
1356 	switch (admin->vtype) {
1357 	case VCAP_TYPE_IS0:
1358 		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1359 		break;
1360 	case VCAP_TYPE_IS2:
1361 		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1362 		break;
1363 	case VCAP_TYPE_ES2:
1364 		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1365 		break;
1366 	default:
1367 		sparx5_vcap_type_err(sparx5, admin, __func__);
1368 		break;
1369 	}
1370 }
1371 
1372 /* Disable lookups per port */
1373 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1374 					     struct vcap_admin *admin)
1375 {
1376 	int portno, lookup;
1377 
1378 	switch (admin->vtype) {
1379 	case VCAP_TYPE_IS0:
1380 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1381 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1382 				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1383 					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1384 					 sparx5,
1385 					 ANA_CL_ADV_CL_CFG(portno, lookup));
1386 		break;
1387 	case VCAP_TYPE_IS2:
1388 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1389 			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1390 				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1391 				 sparx5,
1392 				 ANA_ACL_VCAP_S2_CFG(portno));
1393 		break;
1394 	case VCAP_TYPE_ES2:
1395 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1396 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1397 				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1398 					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1399 					 sparx5,
1400 					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1401 		break;
1402 	default:
1403 		sparx5_vcap_type_err(sparx5, admin, __func__);
1404 		break;
1405 	}
1406 }
1407 
1408 static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1409 {
1410 	if (!admin)
1411 		return;
1412 	mutex_destroy(&admin->lock);
1413 	kfree(admin->cache.keystream);
1414 	kfree(admin->cache.maskstream);
1415 	kfree(admin->cache.actionstream);
1416 	kfree(admin);
1417 }
1418 
1419 /* Allocate a vcap instance with a rule list and a cache area */
1420 static struct vcap_admin *
1421 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1422 			const struct sparx5_vcap_inst *cfg)
1423 {
1424 	struct vcap_admin *admin;
1425 
1426 	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1427 	if (!admin)
1428 		return ERR_PTR(-ENOMEM);
1429 	INIT_LIST_HEAD(&admin->list);
1430 	INIT_LIST_HEAD(&admin->rules);
1431 	INIT_LIST_HEAD(&admin->enabled);
1432 	mutex_init(&admin->lock);
1433 	admin->vtype = cfg->vtype;
1434 	admin->vinst = cfg->vinst;
1435 	admin->ingress = cfg->ingress;
1436 	admin->lookups = cfg->lookups;
1437 	admin->lookups_per_instance = cfg->lookups_per_instance;
1438 	admin->first_cid = cfg->first_cid;
1439 	admin->last_cid = cfg->last_cid;
1440 	admin->cache.keystream =
1441 		kzalloc(STREAMSIZE, GFP_KERNEL);
1442 	admin->cache.maskstream =
1443 		kzalloc(STREAMSIZE, GFP_KERNEL);
1444 	admin->cache.actionstream =
1445 		kzalloc(STREAMSIZE, GFP_KERNEL);
1446 	if (!admin->cache.keystream || !admin->cache.maskstream ||
1447 	    !admin->cache.actionstream) {
1448 		sparx5_vcap_admin_free(admin);
1449 		return ERR_PTR(-ENOMEM);
1450 	}
1451 	return admin;
1452 }
1453 
1454 /* Do block allocations and provide addresses for VCAP instances */
1455 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1456 				    struct vcap_admin *admin,
1457 				    const struct sparx5_vcap_inst *cfg)
1458 {
1459 	int idx, cores;
1460 
1461 	switch (admin->vtype) {
1462 	case VCAP_TYPE_IS0:
1463 	case VCAP_TYPE_IS2:
1464 		/* Super VCAP block mapping and address configuration. Block 0
1465 		 * is assigned addresses 0 through 3071, block 1 is assigned
1466 		 * addresses 3072 though 6143, and so on.
1467 		 */
1468 		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
1469 		     ++idx) {
1470 			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
1471 				VCAP_SUPER_IDX);
1472 			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
1473 				sparx5, VCAP_SUPER_MAP);
1474 		}
1475 		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
1476 		admin->last_used_addr = admin->first_valid_addr +
1477 			cfg->blocks * SUPER_VCAP_BLK_SIZE;
1478 		admin->last_valid_addr = admin->last_used_addr - 1;
1479 		break;
1480 	case VCAP_TYPE_ES2:
1481 		admin->first_valid_addr = 0;
1482 		admin->last_used_addr = cfg->count;
1483 		admin->last_valid_addr = cfg->count - 1;
1484 		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
1485 		for (idx = 0; idx < cores; ++idx) {
1486 			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
1487 				VCAP_ES2_IDX);
1488 			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
1489 				VCAP_ES2_MAP);
1490 		}
1491 		break;
1492 	default:
1493 		sparx5_vcap_type_err(sparx5, admin, __func__);
1494 		break;
1495 	}
1496 }
1497 
1498 /* Allocate a vcap control and vcap instances and configure the system */
1499 int sparx5_vcap_init(struct sparx5 *sparx5)
1500 {
1501 	const struct sparx5_vcap_inst *cfg;
1502 	struct vcap_control *ctrl;
1503 	struct vcap_admin *admin;
1504 	struct dentry *dir;
1505 	int err = 0, idx;
1506 
1507 	/* Create a VCAP control instance that owns the platform specific VCAP
1508 	 * model with VCAP instances and information about keysets, keys,
1509 	 * actionsets and actions
1510 	 * - Create administrative state for each available VCAP
1511 	 *   - Lists of rules
1512 	 *   - Address information
1513 	 *   - Initialize VCAP blocks
1514 	 *   - Configure port keysets
1515 	 */
1516 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
1517 	if (!ctrl)
1518 		return -ENOMEM;
1519 
1520 	sparx5->vcap_ctrl = ctrl;
1521 	/* select the sparx5 VCAP model */
1522 	ctrl->vcaps = sparx5_vcaps;
1523 	ctrl->stats = &sparx5_vcap_stats;
1524 	/* Setup callbacks to allow the API to use the VCAP HW */
1525 	ctrl->ops = &sparx5_vcap_ops;
1526 
1527 	INIT_LIST_HEAD(&ctrl->list);
1528 	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
1529 		cfg = &sparx5_vcap_inst_cfg[idx];
1530 		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
1531 		if (IS_ERR(admin)) {
1532 			err = PTR_ERR(admin);
1533 			pr_err("%s:%d: vcap allocation failed: %d\n",
1534 			       __func__, __LINE__, err);
1535 			return err;
1536 		}
1537 		sparx5_vcap_block_alloc(sparx5, admin, cfg);
1538 		sparx5_vcap_block_init(sparx5, admin);
1539 		if (cfg->vinst == 0)
1540 			sparx5_vcap_port_key_selection(sparx5, admin);
1541 		list_add_tail(&admin->list, &ctrl->list);
1542 	}
1543 	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
1544 	for (idx = 0; idx < SPX5_PORTS; ++idx)
1545 		if (sparx5->ports[idx])
1546 			vcap_port_debugfs(sparx5->dev, dir, ctrl,
1547 					  sparx5->ports[idx]->ndev);
1548 
1549 	return err;
1550 }
1551 
1552 void sparx5_vcap_destroy(struct sparx5 *sparx5)
1553 {
1554 	struct vcap_control *ctrl = sparx5->vcap_ctrl;
1555 	struct vcap_admin *admin, *admin_next;
1556 
1557 	if (!ctrl)
1558 		return;
1559 
1560 	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
1561 		sparx5_vcap_port_key_deselection(sparx5, admin);
1562 		vcap_del_rules(ctrl, admin);
1563 		list_del(&admin->list);
1564 		sparx5_vcap_admin_free(admin);
1565 	}
1566 	kfree(ctrl);
1567 }
1568