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 
sparx5_vcap_type_err(struct sparx5 * sparx5,struct vcap_admin * admin,const char * fname)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 */
sparx5_vcap_wait_super_update(struct sparx5 * sparx5)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 */
sparx5_vcap_wait_es0_update(struct sparx5 * sparx5)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 */
sparx5_vcap_wait_es2_update(struct sparx5 * sparx5)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 */
_sparx5_vcap_range_init(struct sparx5 * sparx5,struct vcap_admin * admin,u32 addr,u32 count)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 */
sparx5_vcap_block_init(struct sparx5 * sparx5,struct vcap_admin * admin)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 */
sparx5_vcap_keyset_name(struct net_device * ndev,enum vcap_keyfield_set keyset)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 */
sparx5_vcap_is0_is_first_chain(struct vcap_rule * rule)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 */
sparx5_vcap_is2_is_first_chain(struct vcap_rule * rule)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 
sparx5_vcap_es2_is_first_chain(struct vcap_rule * rule)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 */
sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule * rule,struct net_device * ndev)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 */
sparx5_vcap_add_wide_port_mask(struct vcap_rule * rule,struct net_device * ndev)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 
sparx5_vcap_add_egress_range_port_mask(struct vcap_rule * rule,struct net_device * ndev)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 */
sparx5_vcap_is0_cid_to_lookup(int cid)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 */
sparx5_vcap_is2_cid_to_lookup(int cid)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 */
sparx5_vcap_es2_cid_to_lookup(int cid)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
sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list * keysetlist,u32 value)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 */
sparx5_vcap_is0_get_port_keysets(struct net_device * ndev,int lookup,struct vcap_keyset_list * keysetlist,u16 l3_proto)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 */
sparx5_vcap_is2_get_port_keysets(struct net_device * ndev,int lookup,struct vcap_keyset_list * keysetlist,u16 l3_proto)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
sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list * keysetlist,u32 value)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 */
sparx5_vcap_es0_get_port_keysets(struct net_device * ndev,struct vcap_keyset_list * keysetlist,u16 l3_proto)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 */
sparx5_vcap_es2_get_port_keysets(struct net_device * ndev,int lookup,struct vcap_keyset_list * keysetlist,u16 l3_proto)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 */
sparx5_vcap_get_port_keyset(struct net_device * ndev,struct vcap_admin * admin,int cid,u16 l3_proto,struct vcap_keyset_list * kslist)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 */
sparx5_vcap_is_known_etype(struct vcap_admin * admin,u16 etype)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
sparx5_vcap_validate_keyset(struct net_device * ndev,struct vcap_admin * admin,struct vcap_rule * rule,struct vcap_keyset_list * kslist,u16 l3_proto)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 
sparx5_vcap_ingress_add_default_fields(struct net_device * ndev,struct vcap_admin * admin,struct vcap_rule * rule)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 
sparx5_vcap_es0_add_default_fields(struct net_device * ndev,struct vcap_admin * admin,struct vcap_rule * rule)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 
sparx5_vcap_es2_add_default_fields(struct net_device * ndev,struct vcap_admin * admin,struct vcap_rule * rule)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 */
sparx5_vcap_add_default_fields(struct net_device * ndev,struct vcap_admin * admin,struct vcap_rule * 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) */
sparx5_vcap_cache_erase(struct vcap_admin * admin)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 
sparx5_vcap_is0_cache_write(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 
sparx5_vcap_is2_cache_write(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 */
sparx5_es0_write_esdx_counter(struct sparx5 * sparx5,struct vcap_admin * admin,u32 id)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 
sparx5_vcap_es0_cache_write(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 
sparx5_vcap_es2_cache_write(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 */
sparx5_vcap_cache_write(struct net_device * ndev,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 
sparx5_vcap_is0_cache_read(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 
sparx5_vcap_is2_cache_read(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 */
sparx5_es0_read_esdx_counter(struct sparx5 * sparx5,struct vcap_admin * admin,u32 id)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 
sparx5_vcap_es0_cache_read(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 
sparx5_vcap_es2_cache_read(struct sparx5 * sparx5,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 */
sparx5_vcap_cache_read(struct net_device * ndev,struct vcap_admin * admin,enum vcap_selection sel,u32 start,u32 count)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 */
sparx5_vcap_range_init(struct net_device * ndev,struct vcap_admin * admin,u32 addr,u32 count)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 
sparx5_vcap_super_update(struct sparx5 * sparx5,enum vcap_command cmd,enum vcap_selection sel,u32 addr)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 
sparx5_vcap_es0_update(struct sparx5 * sparx5,enum vcap_command cmd,enum vcap_selection sel,u32 addr)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 
sparx5_vcap_es2_update(struct sparx5 * sparx5,enum vcap_command cmd,enum vcap_selection sel,u32 addr)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 */
sparx5_vcap_update(struct net_device * ndev,struct vcap_admin * admin,enum vcap_command cmd,enum vcap_selection sel,u32 addr)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 
sparx5_vcap_super_move(struct sparx5 * sparx5,u32 addr,enum vcap_command cmd,u16 mv_num_pos,u16 mv_size)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 
sparx5_vcap_es0_move(struct sparx5 * sparx5,u32 addr,enum vcap_command cmd,u16 mv_num_pos,u16 mv_size)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 
sparx5_vcap_es2_move(struct sparx5 * sparx5,u32 addr,enum vcap_command cmd,u16 mv_num_pos,u16 mv_size)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 */
sparx5_vcap_move(struct net_device * ndev,struct vcap_admin * admin,u32 addr,int offset,int count)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 
sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)1522 static u32 sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)
1523 {
1524 	switch (keyset) {
1525 	case VCAP_KFS_NORMAL_7TUPLE:
1526 		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1527 	case VCAP_KFS_NORMAL_5TUPLE_IP4:
1528 		return VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4;
1529 	default:
1530 		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1531 	}
1532 }
1533 
sparx5_vcap_is0_set_port_keyset(struct net_device * ndev,int lookup,enum vcap_keyfield_set keyset,int l3_proto)1534 static void sparx5_vcap_is0_set_port_keyset(struct net_device *ndev, int lookup,
1535 					    enum vcap_keyfield_set keyset,
1536 					    int l3_proto)
1537 {
1538 	struct sparx5_port *port = netdev_priv(ndev);
1539 	struct sparx5 *sparx5 = port->sparx5;
1540 	int portno = port->portno;
1541 	u32 value;
1542 
1543 	switch (l3_proto) {
1544 	case ETH_P_IP:
1545 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1546 		spx5_rmw(ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(value),
1547 			 ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL,
1548 			 sparx5,
1549 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1550 		break;
1551 	case ETH_P_IPV6:
1552 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1553 		spx5_rmw(ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(value),
1554 			 ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL,
1555 			 sparx5,
1556 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1557 		break;
1558 	default:
1559 		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1560 		spx5_rmw(ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(value),
1561 			 ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL,
1562 			 sparx5,
1563 			 ANA_CL_ADV_CL_CFG(portno, lookup));
1564 		break;
1565 	}
1566 }
1567 
sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)1568 static u32 sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1569 {
1570 	switch (keyset) {
1571 	case VCAP_KFS_ARP:
1572 		return VCAP_IS2_PS_ARP_ARP;
1573 	default:
1574 		return VCAP_IS2_PS_ARP_MAC_ETYPE;
1575 	}
1576 }
1577 
sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)1578 static u32 sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1579 {
1580 	switch (keyset) {
1581 	case VCAP_KFS_MAC_ETYPE:
1582 		return VCAP_IS2_PS_IPV4_UC_MAC_ETYPE;
1583 	case VCAP_KFS_IP4_OTHER:
1584 	case VCAP_KFS_IP4_TCP_UDP:
1585 		return VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER;
1586 	case VCAP_KFS_IP_7TUPLE:
1587 		return VCAP_IS2_PS_IPV4_UC_IP_7TUPLE;
1588 	default:
1589 		return VCAP_KFS_NO_VALUE;
1590 	}
1591 }
1592 
sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)1593 static u32 sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)
1594 {
1595 	switch (keyset) {
1596 	case VCAP_KFS_MAC_ETYPE:
1597 		return VCAP_IS2_PS_IPV6_UC_MAC_ETYPE;
1598 	case VCAP_KFS_IP4_OTHER:
1599 	case VCAP_KFS_IP4_TCP_UDP:
1600 		return VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER;
1601 	case VCAP_KFS_IP_7TUPLE:
1602 		return VCAP_IS2_PS_IPV6_UC_IP_7TUPLE;
1603 	default:
1604 		return VCAP_KFS_NO_VALUE;
1605 	}
1606 }
1607 
sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)1608 static u32 sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)
1609 {
1610 	switch (keyset) {
1611 	case VCAP_KFS_MAC_ETYPE:
1612 		return VCAP_IS2_PS_IPV6_MC_MAC_ETYPE;
1613 	case VCAP_KFS_IP4_OTHER:
1614 	case VCAP_KFS_IP4_TCP_UDP:
1615 		return VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER;
1616 	case VCAP_KFS_IP_7TUPLE:
1617 		return VCAP_IS2_PS_IPV6_MC_IP_7TUPLE;
1618 	default:
1619 		return VCAP_KFS_NO_VALUE;
1620 	}
1621 }
1622 
sparx5_vcap_is2_set_port_keyset(struct net_device * ndev,int lookup,enum vcap_keyfield_set keyset,int l3_proto)1623 static void sparx5_vcap_is2_set_port_keyset(struct net_device *ndev, int lookup,
1624 					    enum vcap_keyfield_set keyset,
1625 					    int l3_proto)
1626 {
1627 	struct sparx5_port *port = netdev_priv(ndev);
1628 	struct sparx5 *sparx5 = port->sparx5;
1629 	int portno = port->portno;
1630 	u32 value;
1631 
1632 	switch (l3_proto) {
1633 	case ETH_P_ARP:
1634 		value = sparx5_vcap_is2_keyset_to_arp_ps(keyset);
1635 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(value),
1636 			 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL,
1637 			 sparx5,
1638 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1639 		break;
1640 	case ETH_P_IP:
1641 		value = sparx5_vcap_is2_keyset_to_ipv4_ps(keyset);
1642 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(value),
1643 			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL,
1644 			 sparx5,
1645 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1646 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(value),
1647 			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL,
1648 			 sparx5,
1649 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1650 		break;
1651 	case ETH_P_IPV6:
1652 		value = sparx5_vcap_is2_keyset_to_ipv6_uc_ps(keyset);
1653 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(value),
1654 			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL,
1655 			 sparx5,
1656 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1657 		value = sparx5_vcap_is2_keyset_to_ipv6_mc_ps(keyset);
1658 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(value),
1659 			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL,
1660 			 sparx5,
1661 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1662 		break;
1663 	default:
1664 		value = VCAP_IS2_PS_NONETH_MAC_ETYPE;
1665 		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(value),
1666 			 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL,
1667 			 sparx5,
1668 			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1669 		break;
1670 	}
1671 }
1672 
sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)1673 static u32 sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1674 {
1675 	switch (keyset) {
1676 	case VCAP_KFS_ARP:
1677 		return VCAP_ES2_PS_ARP_ARP;
1678 	default:
1679 		return VCAP_ES2_PS_ARP_MAC_ETYPE;
1680 	}
1681 }
1682 
sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)1683 static u32 sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1684 {
1685 	switch (keyset) {
1686 	case VCAP_KFS_MAC_ETYPE:
1687 		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1688 	case VCAP_KFS_IP_7TUPLE:
1689 		return VCAP_ES2_PS_IPV4_IP_7TUPLE;
1690 	case VCAP_KFS_IP4_TCP_UDP:
1691 		return VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER;
1692 	case VCAP_KFS_IP4_OTHER:
1693 		return VCAP_ES2_PS_IPV4_IP4_OTHER;
1694 	default:
1695 		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1696 	}
1697 }
1698 
sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)1699 static u32 sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)
1700 {
1701 	switch (keyset) {
1702 	case VCAP_KFS_MAC_ETYPE:
1703 		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1704 	case VCAP_KFS_IP4_TCP_UDP:
1705 	case VCAP_KFS_IP4_OTHER:
1706 		return VCAP_ES2_PS_IPV6_IP4_DOWNGRADE;
1707 	case VCAP_KFS_IP_7TUPLE:
1708 		return VCAP_ES2_PS_IPV6_IP_7TUPLE;
1709 	case VCAP_KFS_IP6_STD:
1710 		return VCAP_ES2_PS_IPV6_IP6_STD;
1711 	default:
1712 		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1713 	}
1714 }
1715 
sparx5_vcap_es2_set_port_keyset(struct net_device * ndev,int lookup,enum vcap_keyfield_set keyset,int l3_proto)1716 static void sparx5_vcap_es2_set_port_keyset(struct net_device *ndev, int lookup,
1717 					    enum vcap_keyfield_set keyset,
1718 					    int l3_proto)
1719 {
1720 	struct sparx5_port *port = netdev_priv(ndev);
1721 	struct sparx5 *sparx5 = port->sparx5;
1722 	int portno = port->portno;
1723 	u32 value;
1724 
1725 	switch (l3_proto) {
1726 	case ETH_P_IP:
1727 		value = sparx5_vcap_es2_keyset_to_ipv4_ps(keyset);
1728 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(value),
1729 			 EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL,
1730 			 sparx5,
1731 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1732 		break;
1733 	case ETH_P_IPV6:
1734 		value = sparx5_vcap_es2_keyset_to_ipv6_ps(keyset);
1735 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(value),
1736 			 EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL,
1737 			 sparx5,
1738 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1739 		break;
1740 	case ETH_P_ARP:
1741 		value = sparx5_vcap_es2_keyset_to_arp_ps(keyset);
1742 		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(value),
1743 			 EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL,
1744 			 sparx5,
1745 			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1746 		break;
1747 	}
1748 }
1749 
1750 /* Change the port keyset for the lookup and protocol */
sparx5_vcap_set_port_keyset(struct net_device * ndev,struct vcap_admin * admin,int cid,u16 l3_proto,enum vcap_keyfield_set keyset,struct vcap_keyset_list * orig)1751 void sparx5_vcap_set_port_keyset(struct net_device *ndev,
1752 				 struct vcap_admin *admin,
1753 				 int cid,
1754 				 u16 l3_proto,
1755 				 enum vcap_keyfield_set keyset,
1756 				 struct vcap_keyset_list *orig)
1757 {
1758 	struct sparx5_port *port;
1759 	int lookup;
1760 
1761 	switch (admin->vtype) {
1762 	case VCAP_TYPE_IS0:
1763 		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
1764 		if (orig)
1765 			sparx5_vcap_is0_get_port_keysets(ndev, lookup, orig,
1766 							 l3_proto);
1767 		sparx5_vcap_is0_set_port_keyset(ndev, lookup, keyset, l3_proto);
1768 		break;
1769 	case VCAP_TYPE_IS2:
1770 		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
1771 		if (orig)
1772 			sparx5_vcap_is2_get_port_keysets(ndev, lookup, orig,
1773 							 l3_proto);
1774 		sparx5_vcap_is2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1775 		break;
1776 	case VCAP_TYPE_ES0:
1777 		break;
1778 	case VCAP_TYPE_ES2:
1779 		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
1780 		if (orig)
1781 			sparx5_vcap_es2_get_port_keysets(ndev, lookup, orig,
1782 							 l3_proto);
1783 		sparx5_vcap_es2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1784 		break;
1785 	default:
1786 		port = netdev_priv(ndev);
1787 		sparx5_vcap_type_err(port->sparx5, admin, __func__);
1788 		break;
1789 	}
1790 }
1791 
1792 /* Enable IS0 lookups per port and set the keyset generation */
sparx5_vcap_is0_port_key_selection(struct sparx5 * sparx5,struct vcap_admin * admin)1793 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1794 					       struct vcap_admin *admin)
1795 {
1796 	int portno, lookup;
1797 	u32 keysel;
1798 
1799 	keysel = VCAP_IS0_KEYSEL(false,
1800 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1801 				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1802 				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1803 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1804 				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1805 				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1806 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1807 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1808 			spx5_wr(keysel, sparx5,
1809 				ANA_CL_ADV_CL_CFG(portno, lookup));
1810 			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1811 				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1812 				 sparx5,
1813 				 ANA_CL_ADV_CL_CFG(portno, lookup));
1814 		}
1815 	}
1816 }
1817 
1818 /* Enable IS2 lookups per port and set the keyset generation */
sparx5_vcap_is2_port_key_selection(struct sparx5 * sparx5,struct vcap_admin * admin)1819 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1820 					       struct vcap_admin *admin)
1821 {
1822 	int portno, lookup;
1823 	u32 keysel;
1824 
1825 	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1826 				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1827 				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1828 				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1829 				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1830 				 VCAP_IS2_PS_ARP_ARP);
1831 	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1832 		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1833 			spx5_wr(keysel, sparx5,
1834 				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1835 		}
1836 	}
1837 	/* IS2 lookups are in bit 0:3 */
1838 	for (portno = 0; portno < SPX5_PORTS; ++portno)
1839 		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1840 			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1841 			 sparx5,
1842 			 ANA_ACL_VCAP_S2_CFG(portno));
1843 }
1844 
1845 /* Enable ES0 lookups per port and set the keyset generation */
sparx5_vcap_es0_port_key_selection(struct sparx5 * sparx5,struct vcap_admin * admin)1846 static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1847 					       struct vcap_admin *admin)
1848 {
1849 	int portno;
1850 	u32 keysel;
1851 
1852 	keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1853 	for (portno = 0; portno < SPX5_PORTS; ++portno)
1854 		spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1855 			 sparx5, REW_RTAG_ETAG_CTRL(portno));
1856 
1857 	spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1858 		 sparx5, REW_ES0_CTRL);
1859 }
1860 
1861 /* Enable ES2 lookups per port and set the keyset generation */
sparx5_vcap_es2_port_key_selection(struct sparx5 * sparx5,struct vcap_admin * admin)1862 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1863 					       struct vcap_admin *admin)
1864 {
1865 	int portno, lookup;
1866 	u32 keysel;
1867 
1868 	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1869 				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1870 				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1871 	for (lookup = 0; lookup < admin->lookups; ++lookup)
1872 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1873 			spx5_wr(keysel, sparx5,
1874 				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1875 }
1876 
1877 /* Enable lookups per port and set the keyset generation */
sparx5_vcap_port_key_selection(struct sparx5 * sparx5,struct vcap_admin * admin)1878 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1879 					   struct vcap_admin *admin)
1880 {
1881 	switch (admin->vtype) {
1882 	case VCAP_TYPE_IS0:
1883 		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1884 		break;
1885 	case VCAP_TYPE_IS2:
1886 		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1887 		break;
1888 	case VCAP_TYPE_ES0:
1889 		sparx5_vcap_es0_port_key_selection(sparx5, admin);
1890 		break;
1891 	case VCAP_TYPE_ES2:
1892 		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1893 		break;
1894 	default:
1895 		sparx5_vcap_type_err(sparx5, admin, __func__);
1896 		break;
1897 	}
1898 }
1899 
1900 /* Disable lookups per port */
sparx5_vcap_port_key_deselection(struct sparx5 * sparx5,struct vcap_admin * admin)1901 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1902 					     struct vcap_admin *admin)
1903 {
1904 	int portno, lookup;
1905 
1906 	switch (admin->vtype) {
1907 	case VCAP_TYPE_IS0:
1908 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1909 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1910 				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1911 					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1912 					 sparx5,
1913 					 ANA_CL_ADV_CL_CFG(portno, lookup));
1914 		break;
1915 	case VCAP_TYPE_IS2:
1916 		for (portno = 0; portno < SPX5_PORTS; ++portno)
1917 			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1918 				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1919 				 sparx5,
1920 				 ANA_ACL_VCAP_S2_CFG(portno));
1921 		break;
1922 	case VCAP_TYPE_ES0:
1923 		spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1924 			 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1925 		break;
1926 	case VCAP_TYPE_ES2:
1927 		for (lookup = 0; lookup < admin->lookups; ++lookup)
1928 			for (portno = 0; portno < SPX5_PORTS; ++portno)
1929 				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1930 					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1931 					 sparx5,
1932 					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1933 		break;
1934 	default:
1935 		sparx5_vcap_type_err(sparx5, admin, __func__);
1936 		break;
1937 	}
1938 }
1939 
sparx5_vcap_admin_free(struct vcap_admin * admin)1940 static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1941 {
1942 	if (!admin)
1943 		return;
1944 	mutex_destroy(&admin->lock);
1945 	kfree(admin->cache.keystream);
1946 	kfree(admin->cache.maskstream);
1947 	kfree(admin->cache.actionstream);
1948 	kfree(admin);
1949 }
1950 
1951 /* Allocate a vcap instance with a rule list and a cache area */
1952 static struct vcap_admin *
sparx5_vcap_admin_alloc(struct sparx5 * sparx5,struct vcap_control * ctrl,const struct sparx5_vcap_inst * cfg)1953 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1954 			const struct sparx5_vcap_inst *cfg)
1955 {
1956 	struct vcap_admin *admin;
1957 
1958 	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1959 	if (!admin)
1960 		return ERR_PTR(-ENOMEM);
1961 	INIT_LIST_HEAD(&admin->list);
1962 	INIT_LIST_HEAD(&admin->rules);
1963 	INIT_LIST_HEAD(&admin->enabled);
1964 	mutex_init(&admin->lock);
1965 	admin->vtype = cfg->vtype;
1966 	admin->vinst = cfg->vinst;
1967 	admin->ingress = cfg->ingress;
1968 	admin->lookups = cfg->lookups;
1969 	admin->lookups_per_instance = cfg->lookups_per_instance;
1970 	admin->first_cid = cfg->first_cid;
1971 	admin->last_cid = cfg->last_cid;
1972 	admin->cache.keystream =
1973 		kzalloc(STREAMSIZE, GFP_KERNEL);
1974 	admin->cache.maskstream =
1975 		kzalloc(STREAMSIZE, GFP_KERNEL);
1976 	admin->cache.actionstream =
1977 		kzalloc(STREAMSIZE, GFP_KERNEL);
1978 	if (!admin->cache.keystream || !admin->cache.maskstream ||
1979 	    !admin->cache.actionstream) {
1980 		sparx5_vcap_admin_free(admin);
1981 		return ERR_PTR(-ENOMEM);
1982 	}
1983 	return admin;
1984 }
1985 
1986 /* Do block allocations and provide addresses for VCAP instances */
sparx5_vcap_block_alloc(struct sparx5 * sparx5,struct vcap_admin * admin,const struct sparx5_vcap_inst * cfg)1987 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1988 				    struct vcap_admin *admin,
1989 				    const struct sparx5_vcap_inst *cfg)
1990 {
1991 	int idx, cores;
1992 
1993 	switch (admin->vtype) {
1994 	case VCAP_TYPE_IS0:
1995 	case VCAP_TYPE_IS2:
1996 		/* Super VCAP block mapping and address configuration. Block 0
1997 		 * is assigned addresses 0 through 3071, block 1 is assigned
1998 		 * addresses 3072 though 6143, and so on.
1999 		 */
2000 		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
2001 		     ++idx) {
2002 			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
2003 				VCAP_SUPER_IDX);
2004 			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
2005 				sparx5, VCAP_SUPER_MAP);
2006 		}
2007 		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
2008 		admin->last_used_addr = admin->first_valid_addr +
2009 			cfg->blocks * SUPER_VCAP_BLK_SIZE;
2010 		admin->last_valid_addr = admin->last_used_addr - 1;
2011 		break;
2012 	case VCAP_TYPE_ES0:
2013 		admin->first_valid_addr = 0;
2014 		admin->last_used_addr = cfg->count;
2015 		admin->last_valid_addr = cfg->count - 1;
2016 		cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
2017 		for (idx = 0; idx < cores; ++idx) {
2018 			spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
2019 				VCAP_ES0_IDX);
2020 			spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
2021 				VCAP_ES0_MAP);
2022 		}
2023 		break;
2024 	case VCAP_TYPE_ES2:
2025 		admin->first_valid_addr = 0;
2026 		admin->last_used_addr = cfg->count;
2027 		admin->last_valid_addr = cfg->count - 1;
2028 		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
2029 		for (idx = 0; idx < cores; ++idx) {
2030 			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
2031 				VCAP_ES2_IDX);
2032 			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
2033 				VCAP_ES2_MAP);
2034 		}
2035 		break;
2036 	default:
2037 		sparx5_vcap_type_err(sparx5, admin, __func__);
2038 		break;
2039 	}
2040 }
2041 
2042 /* Allocate a vcap control and vcap instances and configure the system */
sparx5_vcap_init(struct sparx5 * sparx5)2043 int sparx5_vcap_init(struct sparx5 *sparx5)
2044 {
2045 	const struct sparx5_vcap_inst *cfg;
2046 	struct vcap_control *ctrl;
2047 	struct vcap_admin *admin;
2048 	struct dentry *dir;
2049 	int err = 0, idx;
2050 
2051 	/* Create a VCAP control instance that owns the platform specific VCAP
2052 	 * model with VCAP instances and information about keysets, keys,
2053 	 * actionsets and actions
2054 	 * - Create administrative state for each available VCAP
2055 	 *   - Lists of rules
2056 	 *   - Address information
2057 	 *   - Initialize VCAP blocks
2058 	 *   - Configure port keysets
2059 	 */
2060 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
2061 	if (!ctrl)
2062 		return -ENOMEM;
2063 
2064 	sparx5->vcap_ctrl = ctrl;
2065 	/* select the sparx5 VCAP model */
2066 	ctrl->vcaps = sparx5_vcaps;
2067 	ctrl->stats = &sparx5_vcap_stats;
2068 	/* Setup callbacks to allow the API to use the VCAP HW */
2069 	ctrl->ops = &sparx5_vcap_ops;
2070 
2071 	INIT_LIST_HEAD(&ctrl->list);
2072 	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
2073 		cfg = &sparx5_vcap_inst_cfg[idx];
2074 		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
2075 		if (IS_ERR(admin)) {
2076 			err = PTR_ERR(admin);
2077 			pr_err("%s:%d: vcap allocation failed: %d\n",
2078 			       __func__, __LINE__, err);
2079 			return err;
2080 		}
2081 		sparx5_vcap_block_alloc(sparx5, admin, cfg);
2082 		sparx5_vcap_block_init(sparx5, admin);
2083 		if (cfg->vinst == 0)
2084 			sparx5_vcap_port_key_selection(sparx5, admin);
2085 		list_add_tail(&admin->list, &ctrl->list);
2086 	}
2087 	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
2088 	for (idx = 0; idx < SPX5_PORTS; ++idx)
2089 		if (sparx5->ports[idx])
2090 			vcap_port_debugfs(sparx5->dev, dir, ctrl,
2091 					  sparx5->ports[idx]->ndev);
2092 
2093 	return err;
2094 }
2095 
sparx5_vcap_destroy(struct sparx5 * sparx5)2096 void sparx5_vcap_destroy(struct sparx5 *sparx5)
2097 {
2098 	struct vcap_control *ctrl = sparx5->vcap_ctrl;
2099 	struct vcap_admin *admin, *admin_next;
2100 
2101 	if (!ctrl)
2102 		return;
2103 
2104 	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
2105 		sparx5_vcap_port_key_deselection(sparx5, admin);
2106 		vcap_del_rules(ctrl, admin);
2107 		list_del(&admin->list);
2108 		sparx5_vcap_admin_free(admin);
2109 	}
2110 	kfree(ctrl);
2111 }
2112