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