xref: /openbmc/linux/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c (revision 52b28a93c45d2eb6177f073665ca5e4b2f6a229a)
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 }
856 
857 static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
858 					       struct vcap_admin *admin,
859 					       struct vcap_rule *rule)
860 {
861 	const struct vcap_field *field;
862 	bool is_first;
863 
864 	/* Add egress port mask matching the net device */
865 	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
866 	if (field)
867 		sparx5_vcap_add_egress_range_port_mask(rule, ndev);
868 
869 	/* Add key that selects the first/second lookup */
870 	is_first = sparx5_vcap_es2_is_first_chain(rule);
871 
872 	if (is_first)
873 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
874 				      VCAP_BIT_1);
875 	else
876 		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
877 				      VCAP_BIT_0);
878 }
879 
880 /* API callback used for adding default fields to a rule */
881 static void sparx5_vcap_add_default_fields(struct net_device *ndev,
882 					   struct vcap_admin *admin,
883 					   struct vcap_rule *rule)
884 {
885 	struct sparx5_port *port;
886 
887 	/* add the lookup bit */
888 	switch (admin->vtype) {
889 	case VCAP_TYPE_IS0:
890 	case VCAP_TYPE_IS2:
891 		sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
892 		break;
893 	case VCAP_TYPE_ES0:
894 		sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
895 		break;
896 	case VCAP_TYPE_ES2:
897 		sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
898 		break;
899 	default:
900 		port = netdev_priv(ndev);
901 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
902 		break;
903 	}
904 }
905 
906 /* API callback used for erasing the vcap cache area (not the register area) */
907 static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
908 {
909 	memset(admin->cache.keystream, 0, STREAMSIZE);
910 	memset(admin->cache.maskstream, 0, STREAMSIZE);
911 	memset(admin->cache.actionstream, 0, STREAMSIZE);
912 	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
913 }
914 
915 static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
916 					struct vcap_admin *admin,
917 					enum vcap_selection sel,
918 					u32 start,
919 					u32 count)
920 {
921 	u32 *keystr, *mskstr, *actstr;
922 	int idx;
923 
924 	keystr = &admin->cache.keystream[start];
925 	mskstr = &admin->cache.maskstream[start];
926 	actstr = &admin->cache.actionstream[start];
927 
928 	switch (sel) {
929 	case VCAP_SEL_ENTRY:
930 		for (idx = 0; idx < count; ++idx) {
931 			/* Avoid 'match-off' by setting value & mask */
932 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
933 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
934 			spx5_wr(~mskstr[idx], sparx5,
935 				VCAP_SUPER_VCAP_MASK_DAT(idx));
936 		}
937 		break;
938 	case VCAP_SEL_ACTION:
939 		for (idx = 0; idx < count; ++idx)
940 			spx5_wr(actstr[idx], sparx5,
941 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
942 		break;
943 	case VCAP_SEL_ALL:
944 		pr_err("%s:%d: cannot write all streams at once\n",
945 		       __func__, __LINE__);
946 		break;
947 	default:
948 		break;
949 	}
950 
951 	if (sel & VCAP_SEL_COUNTER)
952 		spx5_wr(admin->cache.counter, sparx5,
953 			VCAP_SUPER_VCAP_CNT_DAT(0));
954 }
955 
956 static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
957 					struct vcap_admin *admin,
958 					enum vcap_selection sel,
959 					u32 start,
960 					u32 count)
961 {
962 	u32 *keystr, *mskstr, *actstr;
963 	int idx;
964 
965 	keystr = &admin->cache.keystream[start];
966 	mskstr = &admin->cache.maskstream[start];
967 	actstr = &admin->cache.actionstream[start];
968 
969 	switch (sel) {
970 	case VCAP_SEL_ENTRY:
971 		for (idx = 0; idx < count; ++idx) {
972 			/* Avoid 'match-off' by setting value & mask */
973 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
974 				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
975 			spx5_wr(~mskstr[idx], sparx5,
976 				VCAP_SUPER_VCAP_MASK_DAT(idx));
977 		}
978 		break;
979 	case VCAP_SEL_ACTION:
980 		for (idx = 0; idx < count; ++idx)
981 			spx5_wr(actstr[idx], sparx5,
982 				VCAP_SUPER_VCAP_ACTION_DAT(idx));
983 		break;
984 	case VCAP_SEL_ALL:
985 		pr_err("%s:%d: cannot write all streams at once\n",
986 		       __func__, __LINE__);
987 		break;
988 	default:
989 		break;
990 	}
991 	if (sel & VCAP_SEL_COUNTER) {
992 		start = start & 0xfff; /* counter limit */
993 		if (admin->vinst == 0)
994 			spx5_wr(admin->cache.counter, sparx5,
995 				ANA_ACL_CNT_A(start));
996 		else
997 			spx5_wr(admin->cache.counter, sparx5,
998 				ANA_ACL_CNT_B(start));
999 		spx5_wr(admin->cache.sticky, sparx5,
1000 			VCAP_SUPER_VCAP_CNT_DAT(0));
1001 	}
1002 }
1003 
1004 /* Use ESDX counters located in the XQS */
1005 static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
1006 					  struct vcap_admin *admin, u32 id)
1007 {
1008 	mutex_lock(&sparx5->queue_stats_lock);
1009 	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1010 	spx5_wr(admin->cache.counter, sparx5,
1011 		XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
1012 	spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1013 	mutex_unlock(&sparx5->queue_stats_lock);
1014 }
1015 
1016 static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
1017 					struct vcap_admin *admin,
1018 					enum vcap_selection sel,
1019 					u32 start,
1020 					u32 count)
1021 {
1022 	u32 *keystr, *mskstr, *actstr;
1023 	int idx;
1024 
1025 	keystr = &admin->cache.keystream[start];
1026 	mskstr = &admin->cache.maskstream[start];
1027 	actstr = &admin->cache.actionstream[start];
1028 
1029 	switch (sel) {
1030 	case VCAP_SEL_ENTRY:
1031 		for (idx = 0; idx < count; ++idx) {
1032 			/* Avoid 'match-off' by setting value & mask */
1033 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1034 				VCAP_ES0_VCAP_ENTRY_DAT(idx));
1035 			spx5_wr(~mskstr[idx], sparx5,
1036 				VCAP_ES0_VCAP_MASK_DAT(idx));
1037 		}
1038 		break;
1039 	case VCAP_SEL_ACTION:
1040 		for (idx = 0; idx < count; ++idx)
1041 			spx5_wr(actstr[idx], sparx5,
1042 				VCAP_ES0_VCAP_ACTION_DAT(idx));
1043 		break;
1044 	case VCAP_SEL_ALL:
1045 		pr_err("%s:%d: cannot write all streams at once\n",
1046 		       __func__, __LINE__);
1047 		break;
1048 	default:
1049 		break;
1050 	}
1051 	if (sel & VCAP_SEL_COUNTER) {
1052 		spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1053 		sparx5_es0_write_esdx_counter(sparx5, admin, start);
1054 	}
1055 }
1056 
1057 static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
1058 					struct vcap_admin *admin,
1059 					enum vcap_selection sel,
1060 					u32 start,
1061 					u32 count)
1062 {
1063 	u32 *keystr, *mskstr, *actstr;
1064 	int idx;
1065 
1066 	keystr = &admin->cache.keystream[start];
1067 	mskstr = &admin->cache.maskstream[start];
1068 	actstr = &admin->cache.actionstream[start];
1069 
1070 	switch (sel) {
1071 	case VCAP_SEL_ENTRY:
1072 		for (idx = 0; idx < count; ++idx) {
1073 			/* Avoid 'match-off' by setting value & mask */
1074 			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1075 				VCAP_ES2_VCAP_ENTRY_DAT(idx));
1076 			spx5_wr(~mskstr[idx], sparx5,
1077 				VCAP_ES2_VCAP_MASK_DAT(idx));
1078 		}
1079 		break;
1080 	case VCAP_SEL_ACTION:
1081 		for (idx = 0; idx < count; ++idx)
1082 			spx5_wr(actstr[idx], sparx5,
1083 				VCAP_ES2_VCAP_ACTION_DAT(idx));
1084 		break;
1085 	case VCAP_SEL_ALL:
1086 		pr_err("%s:%d: cannot write all streams at once\n",
1087 		       __func__, __LINE__);
1088 		break;
1089 	default:
1090 		break;
1091 	}
1092 	if (sel & VCAP_SEL_COUNTER) {
1093 		start = start & 0x7ff; /* counter limit */
1094 		spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
1095 		spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1096 	}
1097 }
1098 
1099 /* API callback used for writing to the VCAP cache */
1100 static void sparx5_vcap_cache_write(struct net_device *ndev,
1101 				    struct vcap_admin *admin,
1102 				    enum vcap_selection sel,
1103 				    u32 start,
1104 				    u32 count)
1105 {
1106 	struct sparx5_port *port = netdev_priv(ndev);
1107 	struct sparx5 *sparx5 = port->sparx5;
1108 
1109 	switch (admin->vtype) {
1110 	case VCAP_TYPE_IS0:
1111 		sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
1112 		break;
1113 	case VCAP_TYPE_IS2:
1114 		sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
1115 		break;
1116 	case VCAP_TYPE_ES0:
1117 		sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
1118 		break;
1119 	case VCAP_TYPE_ES2:
1120 		sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
1121 		break;
1122 	default:
1123 		sparx5_vcap_type_err(sparx5, admin, __func__);
1124 		break;
1125 	}
1126 }
1127 
1128 static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
1129 				       struct vcap_admin *admin,
1130 				       enum vcap_selection sel,
1131 				       u32 start,
1132 				       u32 count)
1133 {
1134 	u32 *keystr, *mskstr, *actstr;
1135 	int idx;
1136 
1137 	keystr = &admin->cache.keystream[start];
1138 	mskstr = &admin->cache.maskstream[start];
1139 	actstr = &admin->cache.actionstream[start];
1140 
1141 	if (sel & VCAP_SEL_ENTRY) {
1142 		for (idx = 0; idx < count; ++idx) {
1143 			keystr[idx] = spx5_rd(sparx5,
1144 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1145 			mskstr[idx] = ~spx5_rd(sparx5,
1146 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1147 		}
1148 	}
1149 
1150 	if (sel & VCAP_SEL_ACTION)
1151 		for (idx = 0; idx < count; ++idx)
1152 			actstr[idx] = spx5_rd(sparx5,
1153 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1154 
1155 	if (sel & VCAP_SEL_COUNTER) {
1156 		admin->cache.counter =
1157 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1158 		admin->cache.sticky =
1159 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1160 	}
1161 }
1162 
1163 static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1164 				       struct vcap_admin *admin,
1165 				       enum vcap_selection sel,
1166 				       u32 start,
1167 				       u32 count)
1168 {
1169 	u32 *keystr, *mskstr, *actstr;
1170 	int idx;
1171 
1172 	keystr = &admin->cache.keystream[start];
1173 	mskstr = &admin->cache.maskstream[start];
1174 	actstr = &admin->cache.actionstream[start];
1175 
1176 	if (sel & VCAP_SEL_ENTRY) {
1177 		for (idx = 0; idx < count; ++idx) {
1178 			keystr[idx] = spx5_rd(sparx5,
1179 					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1180 			mskstr[idx] = ~spx5_rd(sparx5,
1181 					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1182 		}
1183 	}
1184 
1185 	if (sel & VCAP_SEL_ACTION)
1186 		for (idx = 0; idx < count; ++idx)
1187 			actstr[idx] = spx5_rd(sparx5,
1188 					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1189 
1190 	if (sel & VCAP_SEL_COUNTER) {
1191 		start = start & 0xfff; /* counter limit */
1192 		if (admin->vinst == 0)
1193 			admin->cache.counter =
1194 				spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1195 		else
1196 			admin->cache.counter =
1197 				spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1198 		admin->cache.sticky =
1199 			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1200 	}
1201 }
1202 
1203 /* Use ESDX counters located in the XQS */
1204 static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
1205 					 struct vcap_admin *admin, u32 id)
1206 {
1207 	u32 counter;
1208 
1209 	mutex_lock(&sparx5->queue_stats_lock);
1210 	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1211 	counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
1212 		spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1213 	mutex_unlock(&sparx5->queue_stats_lock);
1214 	if (counter)
1215 		admin->cache.counter = counter;
1216 }
1217 
1218 static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
1219 				       struct vcap_admin *admin,
1220 				       enum vcap_selection sel,
1221 				       u32 start,
1222 				       u32 count)
1223 {
1224 	u32 *keystr, *mskstr, *actstr;
1225 	int idx;
1226 
1227 	keystr = &admin->cache.keystream[start];
1228 	mskstr = &admin->cache.maskstream[start];
1229 	actstr = &admin->cache.actionstream[start];
1230 
1231 	if (sel & VCAP_SEL_ENTRY) {
1232 		for (idx = 0; idx < count; ++idx) {
1233 			keystr[idx] =
1234 				spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
1235 			mskstr[idx] =
1236 				~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
1237 		}
1238 	}
1239 
1240 	if (sel & VCAP_SEL_ACTION)
1241 		for (idx = 0; idx < count; ++idx)
1242 			actstr[idx] =
1243 				spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
1244 
1245 	if (sel & VCAP_SEL_COUNTER) {
1246 		admin->cache.counter =
1247 			spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1248 		admin->cache.sticky = admin->cache.counter;
1249 		sparx5_es0_read_esdx_counter(sparx5, admin, start);
1250 	}
1251 }
1252 
1253 static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1254 				       struct vcap_admin *admin,
1255 				       enum vcap_selection sel,
1256 				       u32 start,
1257 				       u32 count)
1258 {
1259 	u32 *keystr, *mskstr, *actstr;
1260 	int idx;
1261 
1262 	keystr = &admin->cache.keystream[start];
1263 	mskstr = &admin->cache.maskstream[start];
1264 	actstr = &admin->cache.actionstream[start];
1265 
1266 	if (sel & VCAP_SEL_ENTRY) {
1267 		for (idx = 0; idx < count; ++idx) {
1268 			keystr[idx] =
1269 				spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1270 			mskstr[idx] =
1271 				~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1272 		}
1273 	}
1274 
1275 	if (sel & VCAP_SEL_ACTION)
1276 		for (idx = 0; idx < count; ++idx)
1277 			actstr[idx] =
1278 				spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1279 
1280 	if (sel & VCAP_SEL_COUNTER) {
1281 		start = start & 0x7ff; /* counter limit */
1282 		admin->cache.counter =
1283 			spx5_rd(sparx5, EACL_ES2_CNT(start));
1284 		admin->cache.sticky =
1285 			spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1286 	}
1287 }
1288 
1289 /* API callback used for reading from the VCAP into the VCAP cache */
1290 static void sparx5_vcap_cache_read(struct net_device *ndev,
1291 				   struct vcap_admin *admin,
1292 				   enum vcap_selection sel,
1293 				   u32 start,
1294 				   u32 count)
1295 {
1296 	struct sparx5_port *port = netdev_priv(ndev);
1297 	struct sparx5 *sparx5 = port->sparx5;
1298 
1299 	switch (admin->vtype) {
1300 	case VCAP_TYPE_IS0:
1301 		sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1302 		break;
1303 	case VCAP_TYPE_IS2:
1304 		sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1305 		break;
1306 	case VCAP_TYPE_ES0:
1307 		sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
1308 		break;
1309 	case VCAP_TYPE_ES2:
1310 		sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1311 		break;
1312 	default:
1313 		sparx5_vcap_type_err(sparx5, admin, __func__);
1314 		break;
1315 	}
1316 }
1317 
1318 /* API callback used for initializing a VCAP address range */
1319 static void sparx5_vcap_range_init(struct net_device *ndev,
1320 				   struct vcap_admin *admin, u32 addr,
1321 				   u32 count)
1322 {
1323 	struct sparx5_port *port = netdev_priv(ndev);
1324 	struct sparx5 *sparx5 = port->sparx5;
1325 
1326 	_sparx5_vcap_range_init(sparx5, admin, addr, count);
1327 }
1328 
1329 static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1330 				     enum vcap_command cmd,
1331 				     enum vcap_selection sel, u32 addr)
1332 {
1333 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1334 
1335 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1336 		VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1337 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1338 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1339 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1340 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1341 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1342 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1343 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1344 		sparx5, VCAP_SUPER_CTRL);
1345 	sparx5_vcap_wait_super_update(sparx5);
1346 }
1347 
1348 static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
1349 				   enum vcap_command cmd,
1350 				   enum vcap_selection sel, u32 addr)
1351 {
1352 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1353 
1354 	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
1355 		VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
1356 	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1357 		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1358 		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1359 		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1360 		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1361 		VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
1362 		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1363 		sparx5, VCAP_ES0_CTRL);
1364 	sparx5_vcap_wait_es0_update(sparx5);
1365 }
1366 
1367 static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1368 				   enum vcap_command cmd,
1369 				   enum vcap_selection sel, u32 addr)
1370 {
1371 	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1372 
1373 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1374 		VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1375 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1376 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1377 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1378 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1379 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1380 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1381 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1382 		sparx5, VCAP_ES2_CTRL);
1383 	sparx5_vcap_wait_es2_update(sparx5);
1384 }
1385 
1386 /* API callback used for updating the VCAP cache */
1387 static void sparx5_vcap_update(struct net_device *ndev,
1388 			       struct vcap_admin *admin, enum vcap_command cmd,
1389 			       enum vcap_selection sel, u32 addr)
1390 {
1391 	struct sparx5_port *port = netdev_priv(ndev);
1392 	struct sparx5 *sparx5 = port->sparx5;
1393 
1394 	switch (admin->vtype) {
1395 	case VCAP_TYPE_IS0:
1396 	case VCAP_TYPE_IS2:
1397 		sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1398 		break;
1399 	case VCAP_TYPE_ES0:
1400 		sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
1401 		break;
1402 	case VCAP_TYPE_ES2:
1403 		sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1404 		break;
1405 	default:
1406 		sparx5_vcap_type_err(sparx5, admin, __func__);
1407 		break;
1408 	}
1409 }
1410 
1411 static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1412 				   u32 addr,
1413 				   enum vcap_command cmd,
1414 				   u16 mv_num_pos,
1415 				   u16 mv_size)
1416 {
1417 	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1418 		VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1419 		sparx5, VCAP_SUPER_CFG);
1420 	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1421 		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1422 		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1423 		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1424 		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1425 		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1426 		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1427 		sparx5, VCAP_SUPER_CTRL);
1428 	sparx5_vcap_wait_super_update(sparx5);
1429 }
1430 
1431 static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
1432 				 u32 addr,
1433 				 enum vcap_command cmd,
1434 				 u16 mv_num_pos,
1435 				 u16 mv_size)
1436 {
1437 	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
1438 		VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
1439 		sparx5, VCAP_ES0_CFG);
1440 	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1441 		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1442 		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
1443 		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
1444 		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1445 		VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
1446 		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1447 		sparx5, VCAP_ES0_CTRL);
1448 	sparx5_vcap_wait_es0_update(sparx5);
1449 }
1450 
1451 static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1452 				 u32 addr,
1453 				 enum vcap_command cmd,
1454 				 u16 mv_num_pos,
1455 				 u16 mv_size)
1456 {
1457 	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1458 		VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1459 		sparx5, VCAP_ES2_CFG);
1460 	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1461 		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1462 		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1463 		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1464 		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1465 		VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1466 		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1467 		sparx5, VCAP_ES2_CTRL);
1468 	sparx5_vcap_wait_es2_update(sparx5);
1469 }
1470 
1471 /* API callback used for moving a block of rules in the VCAP */
1472 static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1473 			     u32 addr, int offset, int count)
1474 {
1475 	struct sparx5_port *port = netdev_priv(ndev);
1476 	struct sparx5 *sparx5 = port->sparx5;
1477 	enum vcap_command cmd;
1478 	u16 mv_num_pos;
1479 	u16 mv_size;
1480 
1481 	mv_size = count - 1;
1482 	if (offset > 0) {
1483 		mv_num_pos = offset - 1;
1484 		cmd = VCAP_CMD_MOVE_DOWN;
1485 	} else {
1486 		mv_num_pos = -offset - 1;
1487 		cmd = VCAP_CMD_MOVE_UP;
1488 	}
1489 
1490 	switch (admin->vtype) {
1491 	case VCAP_TYPE_IS0:
1492 	case VCAP_TYPE_IS2:
1493 		sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1494 		break;
1495 	case VCAP_TYPE_ES0:
1496 		sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1497 		break;
1498 	case VCAP_TYPE_ES2:
1499 		sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1500 		break;
1501 	default:
1502 		sparx5_vcap_type_err(sparx5, admin, __func__);
1503 		break;
1504 	}
1505 }
1506 
1507 static struct vcap_operations sparx5_vcap_ops = {
1508 	.validate_keyset = sparx5_vcap_validate_keyset,
1509 	.add_default_fields = sparx5_vcap_add_default_fields,
1510 	.cache_erase = sparx5_vcap_cache_erase,
1511 	.cache_write = sparx5_vcap_cache_write,
1512 	.cache_read = sparx5_vcap_cache_read,
1513 	.init = sparx5_vcap_range_init,
1514 	.update = sparx5_vcap_update,
1515 	.move = sparx5_vcap_move,
1516 	.port_info = sparx5_port_info,
1517 };
1518 
1519 /* Enable IS0 lookups per port and set the keyset generation */
1520 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1521 					       struct vcap_admin *admin)
1522 {
1523 	int portno, lookup;
1524 	u32 keysel;
1525 
1526 	keysel = VCAP_IS0_KEYSEL(false,
1527 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1528 				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1529 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1530 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1531 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1532 				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1533 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1534 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1535 			spx5_wr(keysel, sparx5,
1536 				ANA_CL_ADV_CL_CFG(portno, lookup));
1537 			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1538 				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1539 				 sparx5,
1540 				 ANA_CL_ADV_CL_CFG(portno, lookup));
1541 		}
1542 	}
1543 }
1544 
1545 /* Enable IS2 lookups per port and set the keyset generation */
1546 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1547 					       struct vcap_admin *admin)
1548 {
1549 	int portno, lookup;
1550 	u32 keysel;
1551 
1552 	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1553 				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1554 				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1555 				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1556 				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1557 				 VCAP_IS2_PS_ARP_ARP);
1558 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1559 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1560 			spx5_wr(keysel, sparx5,
1561 				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1562 		}
1563 	}
1564 	/* IS2 lookups are in bit 0:3 */
1565 	for (portno = 0; portno < SPX5_PORTS; ++portno)
1566 		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1567 			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1568 			 sparx5,
1569 			 ANA_ACL_VCAP_S2_CFG(portno));
1570 }
1571 
1572 /* Enable ES0 lookups per port and set the keyset generation */
1573 static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1574 					       struct vcap_admin *admin)
1575 {
1576 	int portno;
1577 	u32 keysel;
1578 
1579 	keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1580 	for (portno = 0; portno < SPX5_PORTS; ++portno)
1581 		spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1582 			 sparx5, REW_RTAG_ETAG_CTRL(portno));
1583 
1584 	spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1585 		 sparx5, REW_ES0_CTRL);
1586 }
1587 
1588 /* Enable ES2 lookups per port and set the keyset generation */
1589 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1590 					       struct vcap_admin *admin)
1591 {
1592 	int portno, lookup;
1593 	u32 keysel;
1594 
1595 	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1596 				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1597 				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1598 	for (lookup = 0; lookup < admin->lookups; ++lookup)
1599 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1600 			spx5_wr(keysel, sparx5,
1601 				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1602 }
1603 
1604 /* Enable lookups per port and set the keyset generation */
1605 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1606 					   struct vcap_admin *admin)
1607 {
1608 	switch (admin->vtype) {
1609 	case VCAP_TYPE_IS0:
1610 		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1611 		break;
1612 	case VCAP_TYPE_IS2:
1613 		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1614 		break;
1615 	case VCAP_TYPE_ES0:
1616 		sparx5_vcap_es0_port_key_selection(sparx5, admin);
1617 		break;
1618 	case VCAP_TYPE_ES2:
1619 		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1620 		break;
1621 	default:
1622 		sparx5_vcap_type_err(sparx5, admin, __func__);
1623 		break;
1624 	}
1625 }
1626 
1627 /* Disable lookups per port */
1628 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1629 					     struct vcap_admin *admin)
1630 {
1631 	int portno, lookup;
1632 
1633 	switch (admin->vtype) {
1634 	case VCAP_TYPE_IS0:
1635 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1636 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1637 				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1638 					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1639 					 sparx5,
1640 					 ANA_CL_ADV_CL_CFG(portno, lookup));
1641 		break;
1642 	case VCAP_TYPE_IS2:
1643 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1644 			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1645 				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1646 				 sparx5,
1647 				 ANA_ACL_VCAP_S2_CFG(portno));
1648 		break;
1649 	case VCAP_TYPE_ES0:
1650 		spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1651 			 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1652 		break;
1653 	case VCAP_TYPE_ES2:
1654 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1655 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1656 				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1657 					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1658 					 sparx5,
1659 					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1660 		break;
1661 	default:
1662 		sparx5_vcap_type_err(sparx5, admin, __func__);
1663 		break;
1664 	}
1665 }
1666 
1667 static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1668 {
1669 	if (!admin)
1670 		return;
1671 	mutex_destroy(&admin->lock);
1672 	kfree(admin->cache.keystream);
1673 	kfree(admin->cache.maskstream);
1674 	kfree(admin->cache.actionstream);
1675 	kfree(admin);
1676 }
1677 
1678 /* Allocate a vcap instance with a rule list and a cache area */
1679 static struct vcap_admin *
1680 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1681 			const struct sparx5_vcap_inst *cfg)
1682 {
1683 	struct vcap_admin *admin;
1684 
1685 	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1686 	if (!admin)
1687 		return ERR_PTR(-ENOMEM);
1688 	INIT_LIST_HEAD(&admin->list);
1689 	INIT_LIST_HEAD(&admin->rules);
1690 	INIT_LIST_HEAD(&admin->enabled);
1691 	mutex_init(&admin->lock);
1692 	admin->vtype = cfg->vtype;
1693 	admin->vinst = cfg->vinst;
1694 	admin->ingress = cfg->ingress;
1695 	admin->lookups = cfg->lookups;
1696 	admin->lookups_per_instance = cfg->lookups_per_instance;
1697 	admin->first_cid = cfg->first_cid;
1698 	admin->last_cid = cfg->last_cid;
1699 	admin->cache.keystream =
1700 		kzalloc(STREAMSIZE, GFP_KERNEL);
1701 	admin->cache.maskstream =
1702 		kzalloc(STREAMSIZE, GFP_KERNEL);
1703 	admin->cache.actionstream =
1704 		kzalloc(STREAMSIZE, GFP_KERNEL);
1705 	if (!admin->cache.keystream || !admin->cache.maskstream ||
1706 	    !admin->cache.actionstream) {
1707 		sparx5_vcap_admin_free(admin);
1708 		return ERR_PTR(-ENOMEM);
1709 	}
1710 	return admin;
1711 }
1712 
1713 /* Do block allocations and provide addresses for VCAP instances */
1714 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1715 				    struct vcap_admin *admin,
1716 				    const struct sparx5_vcap_inst *cfg)
1717 {
1718 	int idx, cores;
1719 
1720 	switch (admin->vtype) {
1721 	case VCAP_TYPE_IS0:
1722 	case VCAP_TYPE_IS2:
1723 		/* Super VCAP block mapping and address configuration. Block 0
1724 		 * is assigned addresses 0 through 3071, block 1 is assigned
1725 		 * addresses 3072 though 6143, and so on.
1726 		 */
1727 		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
1728 		     ++idx) {
1729 			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
1730 				VCAP_SUPER_IDX);
1731 			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
1732 				sparx5, VCAP_SUPER_MAP);
1733 		}
1734 		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
1735 		admin->last_used_addr = admin->first_valid_addr +
1736 			cfg->blocks * SUPER_VCAP_BLK_SIZE;
1737 		admin->last_valid_addr = admin->last_used_addr - 1;
1738 		break;
1739 	case VCAP_TYPE_ES0:
1740 		admin->first_valid_addr = 0;
1741 		admin->last_used_addr = cfg->count;
1742 		admin->last_valid_addr = cfg->count - 1;
1743 		cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
1744 		for (idx = 0; idx < cores; ++idx) {
1745 			spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
1746 				VCAP_ES0_IDX);
1747 			spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
1748 				VCAP_ES0_MAP);
1749 		}
1750 		break;
1751 	case VCAP_TYPE_ES2:
1752 		admin->first_valid_addr = 0;
1753 		admin->last_used_addr = cfg->count;
1754 		admin->last_valid_addr = cfg->count - 1;
1755 		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
1756 		for (idx = 0; idx < cores; ++idx) {
1757 			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
1758 				VCAP_ES2_IDX);
1759 			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
1760 				VCAP_ES2_MAP);
1761 		}
1762 		break;
1763 	default:
1764 		sparx5_vcap_type_err(sparx5, admin, __func__);
1765 		break;
1766 	}
1767 }
1768 
1769 /* Allocate a vcap control and vcap instances and configure the system */
1770 int sparx5_vcap_init(struct sparx5 *sparx5)
1771 {
1772 	const struct sparx5_vcap_inst *cfg;
1773 	struct vcap_control *ctrl;
1774 	struct vcap_admin *admin;
1775 	struct dentry *dir;
1776 	int err = 0, idx;
1777 
1778 	/* Create a VCAP control instance that owns the platform specific VCAP
1779 	 * model with VCAP instances and information about keysets, keys,
1780 	 * actionsets and actions
1781 	 * - Create administrative state for each available VCAP
1782 	 *   - Lists of rules
1783 	 *   - Address information
1784 	 *   - Initialize VCAP blocks
1785 	 *   - Configure port keysets
1786 	 */
1787 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
1788 	if (!ctrl)
1789 		return -ENOMEM;
1790 
1791 	sparx5->vcap_ctrl = ctrl;
1792 	/* select the sparx5 VCAP model */
1793 	ctrl->vcaps = sparx5_vcaps;
1794 	ctrl->stats = &sparx5_vcap_stats;
1795 	/* Setup callbacks to allow the API to use the VCAP HW */
1796 	ctrl->ops = &sparx5_vcap_ops;
1797 
1798 	INIT_LIST_HEAD(&ctrl->list);
1799 	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
1800 		cfg = &sparx5_vcap_inst_cfg[idx];
1801 		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
1802 		if (IS_ERR(admin)) {
1803 			err = PTR_ERR(admin);
1804 			pr_err("%s:%d: vcap allocation failed: %d\n",
1805 			       __func__, __LINE__, err);
1806 			return err;
1807 		}
1808 		sparx5_vcap_block_alloc(sparx5, admin, cfg);
1809 		sparx5_vcap_block_init(sparx5, admin);
1810 		if (cfg->vinst == 0)
1811 			sparx5_vcap_port_key_selection(sparx5, admin);
1812 		list_add_tail(&admin->list, &ctrl->list);
1813 	}
1814 	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
1815 	for (idx = 0; idx < SPX5_PORTS; ++idx)
1816 		if (sparx5->ports[idx])
1817 			vcap_port_debugfs(sparx5->dev, dir, ctrl,
1818 					  sparx5->ports[idx]->ndev);
1819 
1820 	return err;
1821 }
1822 
1823 void sparx5_vcap_destroy(struct sparx5 *sparx5)
1824 {
1825 	struct vcap_control *ctrl = sparx5->vcap_ctrl;
1826 	struct vcap_admin *admin, *admin_next;
1827 
1828 	if (!ctrl)
1829 		return;
1830 
1831 	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
1832 		sparx5_vcap_port_key_deselection(sparx5, admin);
1833 		vcap_del_rules(ctrl, admin);
1834 		list_del(&admin->list);
1835 		sparx5_vcap_admin_free(admin);
1836 	}
1837 	kfree(ctrl);
1838 }
1839