1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip VCAP API
3  *
4  * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
5  */
6 
7 #include <net/tcp.h>
8 
9 #include "sparx5_tc.h"
10 #include "vcap_api.h"
11 #include "vcap_api_client.h"
12 #include "sparx5_main.h"
13 #include "sparx5_vcap_impl.h"
14 
15 #define SPX5_MAX_RULE_SIZE 13 /* allows X1, X2, X4, X6 and X12 rules */
16 
17 /* Collect keysets and type ids for multiple rules per size */
18 struct sparx5_wildcard_rule {
19 	bool selected;
20 	u8 value;
21 	u8 mask;
22 	enum vcap_keyfield_set keyset;
23 };
24 
25 struct sparx5_multiple_rules {
26 	struct sparx5_wildcard_rule rule[SPX5_MAX_RULE_SIZE];
27 };
28 
29 struct sparx5_tc_flower_parse_usage {
30 	struct flow_cls_offload *fco;
31 	struct flow_rule *frule;
32 	struct vcap_rule *vrule;
33 	struct vcap_admin *admin;
34 	u16 l3_proto;
35 	u8 l4_proto;
36 	unsigned int used_keys;
37 };
38 
39 enum sparx5_is2_arp_opcode {
40 	SPX5_IS2_ARP_REQUEST,
41 	SPX5_IS2_ARP_REPLY,
42 	SPX5_IS2_RARP_REQUEST,
43 	SPX5_IS2_RARP_REPLY,
44 };
45 
46 enum tc_arp_opcode {
47 	TC_ARP_OP_RESERVED,
48 	TC_ARP_OP_REQUEST,
49 	TC_ARP_OP_REPLY,
50 };
51 
52 static int sparx5_tc_flower_handler_ethaddr_usage(struct sparx5_tc_flower_parse_usage *st)
53 {
54 	enum vcap_key_field smac_key = VCAP_KF_L2_SMAC;
55 	enum vcap_key_field dmac_key = VCAP_KF_L2_DMAC;
56 	struct flow_match_eth_addrs match;
57 	struct vcap_u48_key smac, dmac;
58 	int err = 0;
59 
60 	flow_rule_match_eth_addrs(st->frule, &match);
61 
62 	if (!is_zero_ether_addr(match.mask->src)) {
63 		vcap_netbytes_copy(smac.value, match.key->src, ETH_ALEN);
64 		vcap_netbytes_copy(smac.mask, match.mask->src, ETH_ALEN);
65 		err = vcap_rule_add_key_u48(st->vrule, smac_key, &smac);
66 		if (err)
67 			goto out;
68 	}
69 
70 	if (!is_zero_ether_addr(match.mask->dst)) {
71 		vcap_netbytes_copy(dmac.value, match.key->dst, ETH_ALEN);
72 		vcap_netbytes_copy(dmac.mask, match.mask->dst, ETH_ALEN);
73 		err = vcap_rule_add_key_u48(st->vrule, dmac_key, &dmac);
74 		if (err)
75 			goto out;
76 	}
77 
78 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS);
79 
80 	return err;
81 
82 out:
83 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "eth_addr parse error");
84 	return err;
85 }
86 
87 static int
88 sparx5_tc_flower_handler_ipv4_usage(struct sparx5_tc_flower_parse_usage *st)
89 {
90 	int err = 0;
91 
92 	if (st->l3_proto == ETH_P_IP) {
93 		struct flow_match_ipv4_addrs mt;
94 
95 		flow_rule_match_ipv4_addrs(st->frule, &mt);
96 		if (mt.mask->src) {
97 			err = vcap_rule_add_key_u32(st->vrule,
98 						    VCAP_KF_L3_IP4_SIP,
99 						    be32_to_cpu(mt.key->src),
100 						    be32_to_cpu(mt.mask->src));
101 			if (err)
102 				goto out;
103 		}
104 		if (mt.mask->dst) {
105 			err = vcap_rule_add_key_u32(st->vrule,
106 						    VCAP_KF_L3_IP4_DIP,
107 						    be32_to_cpu(mt.key->dst),
108 						    be32_to_cpu(mt.mask->dst));
109 			if (err)
110 				goto out;
111 		}
112 	}
113 
114 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS);
115 
116 	return err;
117 
118 out:
119 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ipv4_addr parse error");
120 	return err;
121 }
122 
123 static int
124 sparx5_tc_flower_handler_ipv6_usage(struct sparx5_tc_flower_parse_usage *st)
125 {
126 	int err = 0;
127 
128 	if (st->l3_proto == ETH_P_IPV6) {
129 		struct flow_match_ipv6_addrs mt;
130 		struct vcap_u128_key sip;
131 		struct vcap_u128_key dip;
132 
133 		flow_rule_match_ipv6_addrs(st->frule, &mt);
134 		/* Check if address masks are non-zero */
135 		if (!ipv6_addr_any(&mt.mask->src)) {
136 			vcap_netbytes_copy(sip.value, mt.key->src.s6_addr, 16);
137 			vcap_netbytes_copy(sip.mask, mt.mask->src.s6_addr, 16);
138 			err = vcap_rule_add_key_u128(st->vrule,
139 						     VCAP_KF_L3_IP6_SIP, &sip);
140 			if (err)
141 				goto out;
142 		}
143 		if (!ipv6_addr_any(&mt.mask->dst)) {
144 			vcap_netbytes_copy(dip.value, mt.key->dst.s6_addr, 16);
145 			vcap_netbytes_copy(dip.mask, mt.mask->dst.s6_addr, 16);
146 			err = vcap_rule_add_key_u128(st->vrule,
147 						     VCAP_KF_L3_IP6_DIP, &dip);
148 			if (err)
149 				goto out;
150 		}
151 	}
152 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS);
153 	return err;
154 out:
155 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ipv6_addr parse error");
156 	return err;
157 }
158 
159 static int
160 sparx5_tc_flower_handler_control_usage(struct sparx5_tc_flower_parse_usage *st)
161 {
162 	struct flow_match_control mt;
163 	u32 value, mask;
164 	int err = 0;
165 
166 	flow_rule_match_control(st->frule, &mt);
167 
168 	if (mt.mask->flags) {
169 		if (mt.mask->flags & FLOW_DIS_FIRST_FRAG) {
170 			if (mt.key->flags & FLOW_DIS_FIRST_FRAG) {
171 				value = 1; /* initial fragment */
172 				mask = 0x3;
173 			} else {
174 				if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
175 					value = 3; /* follow up fragment */
176 					mask = 0x3;
177 				} else {
178 					value = 0; /* no fragment */
179 					mask = 0x3;
180 				}
181 			}
182 		} else {
183 			if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
184 				value = 3; /* follow up fragment */
185 				mask = 0x3;
186 			} else {
187 				value = 0; /* no fragment */
188 				mask = 0x3;
189 			}
190 		}
191 
192 		err = vcap_rule_add_key_u32(st->vrule,
193 					    VCAP_KF_L3_FRAGMENT_TYPE,
194 					    value, mask);
195 		if (err)
196 			goto out;
197 	}
198 
199 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_CONTROL);
200 
201 	return err;
202 
203 out:
204 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ip_frag parse error");
205 	return err;
206 }
207 
208 static int
209 sparx5_tc_flower_handler_portnum_usage(struct sparx5_tc_flower_parse_usage *st)
210 {
211 	struct flow_match_ports mt;
212 	u16 value, mask;
213 	int err = 0;
214 
215 	flow_rule_match_ports(st->frule, &mt);
216 
217 	if (mt.mask->src) {
218 		value = be16_to_cpu(mt.key->src);
219 		mask = be16_to_cpu(mt.mask->src);
220 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L4_SPORT, value,
221 					    mask);
222 		if (err)
223 			goto out;
224 	}
225 
226 	if (mt.mask->dst) {
227 		value = be16_to_cpu(mt.key->dst);
228 		mask = be16_to_cpu(mt.mask->dst);
229 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L4_DPORT, value,
230 					    mask);
231 		if (err)
232 			goto out;
233 	}
234 
235 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_PORTS);
236 
237 	return err;
238 
239 out:
240 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "port parse error");
241 	return err;
242 }
243 
244 static int
245 sparx5_tc_flower_handler_basic_usage(struct sparx5_tc_flower_parse_usage *st)
246 {
247 	struct flow_match_basic mt;
248 	int err = 0;
249 
250 	flow_rule_match_basic(st->frule, &mt);
251 
252 	if (mt.mask->n_proto) {
253 		st->l3_proto = be16_to_cpu(mt.key->n_proto);
254 		if (!sparx5_vcap_is_known_etype(st->admin, st->l3_proto)) {
255 			err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ETYPE,
256 						    st->l3_proto, ~0);
257 			if (err)
258 				goto out;
259 		} else if (st->l3_proto == ETH_P_IP) {
260 			err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_IP4_IS,
261 						    VCAP_BIT_1);
262 			if (err)
263 				goto out;
264 		} else if (st->l3_proto == ETH_P_IPV6) {
265 			err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_IP4_IS,
266 						    VCAP_BIT_0);
267 			if (err)
268 				goto out;
269 			if (st->admin->vtype == VCAP_TYPE_IS0) {
270 				err = vcap_rule_add_key_bit(st->vrule,
271 							    VCAP_KF_IP_SNAP_IS,
272 							    VCAP_BIT_1);
273 				if (err)
274 					goto out;
275 			}
276 
277 		}
278 	}
279 
280 	if (mt.mask->ip_proto) {
281 		st->l4_proto = mt.key->ip_proto;
282 		if (st->l4_proto == IPPROTO_TCP) {
283 			err = vcap_rule_add_key_bit(st->vrule,
284 						    VCAP_KF_TCP_IS,
285 						    VCAP_BIT_1);
286 			if (err)
287 				goto out;
288 		} else if (st->l4_proto == IPPROTO_UDP) {
289 			err = vcap_rule_add_key_bit(st->vrule,
290 						    VCAP_KF_TCP_IS,
291 						    VCAP_BIT_0);
292 			if (err)
293 				goto out;
294 			if (st->admin->vtype == VCAP_TYPE_IS0) {
295 				err = vcap_rule_add_key_bit(st->vrule,
296 							    VCAP_KF_TCP_UDP_IS,
297 							    VCAP_BIT_1);
298 				if (err)
299 					goto out;
300 			}
301 		} else {
302 			err = vcap_rule_add_key_u32(st->vrule,
303 						    VCAP_KF_L3_IP_PROTO,
304 						    st->l4_proto, ~0);
305 			if (err)
306 				goto out;
307 		}
308 	}
309 
310 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_BASIC);
311 
312 	return err;
313 
314 out:
315 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ip_proto parse error");
316 	return err;
317 }
318 
319 static int
320 sparx5_tc_flower_handler_cvlan_usage(struct sparx5_tc_flower_parse_usage *st)
321 {
322 	enum vcap_key_field vid_key = VCAP_KF_8021Q_VID0;
323 	enum vcap_key_field pcp_key = VCAP_KF_8021Q_PCP0;
324 	struct flow_match_vlan mt;
325 	u16 tpid;
326 	int err;
327 
328 	if (st->admin->vtype != VCAP_TYPE_IS0)
329 		return -EINVAL;
330 
331 	flow_rule_match_cvlan(st->frule, &mt);
332 
333 	tpid = be16_to_cpu(mt.key->vlan_tpid);
334 
335 	if (tpid == ETH_P_8021Q) {
336 		vid_key = VCAP_KF_8021Q_VID1;
337 		pcp_key = VCAP_KF_8021Q_PCP1;
338 	}
339 
340 	if (mt.mask->vlan_id) {
341 		err = vcap_rule_add_key_u32(st->vrule, vid_key,
342 					    mt.key->vlan_id,
343 					    mt.mask->vlan_id);
344 		if (err)
345 			goto out;
346 	}
347 
348 	if (mt.mask->vlan_priority) {
349 		err = vcap_rule_add_key_u32(st->vrule, pcp_key,
350 					    mt.key->vlan_priority,
351 					    mt.mask->vlan_priority);
352 		if (err)
353 			goto out;
354 	}
355 
356 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_CVLAN);
357 
358 	return 0;
359 out:
360 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "cvlan parse error");
361 	return err;
362 }
363 
364 static int
365 sparx5_tc_flower_handler_vlan_usage(struct sparx5_tc_flower_parse_usage *st)
366 {
367 	enum vcap_key_field vid_key = VCAP_KF_8021Q_VID_CLS;
368 	enum vcap_key_field pcp_key = VCAP_KF_8021Q_PCP_CLS;
369 	struct flow_match_vlan mt;
370 	int err;
371 
372 	flow_rule_match_vlan(st->frule, &mt);
373 
374 	if (st->admin->vtype == VCAP_TYPE_IS0) {
375 		vid_key = VCAP_KF_8021Q_VID0;
376 		pcp_key = VCAP_KF_8021Q_PCP0;
377 	}
378 
379 	if (mt.mask->vlan_id) {
380 		err = vcap_rule_add_key_u32(st->vrule, vid_key,
381 					    mt.key->vlan_id,
382 					    mt.mask->vlan_id);
383 		if (err)
384 			goto out;
385 	}
386 
387 	if (mt.mask->vlan_priority) {
388 		err = vcap_rule_add_key_u32(st->vrule, pcp_key,
389 					    mt.key->vlan_priority,
390 					    mt.mask->vlan_priority);
391 		if (err)
392 			goto out;
393 	}
394 
395 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_VLAN);
396 
397 	return 0;
398 out:
399 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "vlan parse error");
400 	return err;
401 }
402 
403 static int
404 sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st)
405 {
406 	struct flow_match_tcp mt;
407 	u16 tcp_flags_mask;
408 	u16 tcp_flags_key;
409 	enum vcap_bit val;
410 	int err = 0;
411 
412 	flow_rule_match_tcp(st->frule, &mt);
413 	tcp_flags_key = be16_to_cpu(mt.key->flags);
414 	tcp_flags_mask = be16_to_cpu(mt.mask->flags);
415 
416 	if (tcp_flags_mask & TCPHDR_FIN) {
417 		val = VCAP_BIT_0;
418 		if (tcp_flags_key & TCPHDR_FIN)
419 			val = VCAP_BIT_1;
420 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_FIN, val);
421 		if (err)
422 			goto out;
423 	}
424 
425 	if (tcp_flags_mask & TCPHDR_SYN) {
426 		val = VCAP_BIT_0;
427 		if (tcp_flags_key & TCPHDR_SYN)
428 			val = VCAP_BIT_1;
429 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_SYN, val);
430 		if (err)
431 			goto out;
432 	}
433 
434 	if (tcp_flags_mask & TCPHDR_RST) {
435 		val = VCAP_BIT_0;
436 		if (tcp_flags_key & TCPHDR_RST)
437 			val = VCAP_BIT_1;
438 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_RST, val);
439 		if (err)
440 			goto out;
441 	}
442 
443 	if (tcp_flags_mask & TCPHDR_PSH) {
444 		val = VCAP_BIT_0;
445 		if (tcp_flags_key & TCPHDR_PSH)
446 			val = VCAP_BIT_1;
447 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_PSH, val);
448 		if (err)
449 			goto out;
450 	}
451 
452 	if (tcp_flags_mask & TCPHDR_ACK) {
453 		val = VCAP_BIT_0;
454 		if (tcp_flags_key & TCPHDR_ACK)
455 			val = VCAP_BIT_1;
456 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_ACK, val);
457 		if (err)
458 			goto out;
459 	}
460 
461 	if (tcp_flags_mask & TCPHDR_URG) {
462 		val = VCAP_BIT_0;
463 		if (tcp_flags_key & TCPHDR_URG)
464 			val = VCAP_BIT_1;
465 		err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_URG, val);
466 		if (err)
467 			goto out;
468 	}
469 
470 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_TCP);
471 
472 	return err;
473 
474 out:
475 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "tcp_flags parse error");
476 	return err;
477 }
478 
479 static int
480 sparx5_tc_flower_handler_arp_usage(struct sparx5_tc_flower_parse_usage *st)
481 {
482 	struct flow_match_arp mt;
483 	u16 value, mask;
484 	u32 ipval, ipmsk;
485 	int err;
486 
487 	flow_rule_match_arp(st->frule, &mt);
488 
489 	if (mt.mask->op) {
490 		mask = 0x3;
491 		if (st->l3_proto == ETH_P_ARP) {
492 			value = mt.key->op == TC_ARP_OP_REQUEST ?
493 					SPX5_IS2_ARP_REQUEST :
494 					SPX5_IS2_ARP_REPLY;
495 		} else { /* RARP */
496 			value = mt.key->op == TC_ARP_OP_REQUEST ?
497 					SPX5_IS2_RARP_REQUEST :
498 					SPX5_IS2_RARP_REPLY;
499 		}
500 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ARP_OPCODE,
501 					    value, mask);
502 		if (err)
503 			goto out;
504 	}
505 
506 	/* The IS2 ARP keyset does not support ARP hardware addresses */
507 	if (!is_zero_ether_addr(mt.mask->sha) ||
508 	    !is_zero_ether_addr(mt.mask->tha)) {
509 		err = -EINVAL;
510 		goto out;
511 	}
512 
513 	if (mt.mask->sip) {
514 		ipval = be32_to_cpu((__force __be32)mt.key->sip);
515 		ipmsk = be32_to_cpu((__force __be32)mt.mask->sip);
516 
517 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_SIP,
518 					    ipval, ipmsk);
519 		if (err)
520 			goto out;
521 	}
522 
523 	if (mt.mask->tip) {
524 		ipval = be32_to_cpu((__force __be32)mt.key->tip);
525 		ipmsk = be32_to_cpu((__force __be32)mt.mask->tip);
526 
527 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_DIP,
528 					    ipval, ipmsk);
529 		if (err)
530 			goto out;
531 	}
532 
533 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_ARP);
534 
535 	return 0;
536 
537 out:
538 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "arp parse error");
539 	return err;
540 }
541 
542 static int
543 sparx5_tc_flower_handler_ip_usage(struct sparx5_tc_flower_parse_usage *st)
544 {
545 	struct flow_match_ip mt;
546 	int err = 0;
547 
548 	flow_rule_match_ip(st->frule, &mt);
549 
550 	if (mt.mask->tos) {
551 		err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_TOS,
552 					    mt.key->tos,
553 					    mt.mask->tos);
554 		if (err)
555 			goto out;
556 	}
557 
558 	st->used_keys |= BIT(FLOW_DISSECTOR_KEY_IP);
559 
560 	return err;
561 
562 out:
563 	NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ip_tos parse error");
564 	return err;
565 }
566 
567 static int (*sparx5_tc_flower_usage_handlers[])(struct sparx5_tc_flower_parse_usage *st) = {
568 	[FLOW_DISSECTOR_KEY_ETH_ADDRS] = sparx5_tc_flower_handler_ethaddr_usage,
569 	[FLOW_DISSECTOR_KEY_IPV4_ADDRS] = sparx5_tc_flower_handler_ipv4_usage,
570 	[FLOW_DISSECTOR_KEY_IPV6_ADDRS] = sparx5_tc_flower_handler_ipv6_usage,
571 	[FLOW_DISSECTOR_KEY_CONTROL] = sparx5_tc_flower_handler_control_usage,
572 	[FLOW_DISSECTOR_KEY_PORTS] = sparx5_tc_flower_handler_portnum_usage,
573 	[FLOW_DISSECTOR_KEY_BASIC] = sparx5_tc_flower_handler_basic_usage,
574 	[FLOW_DISSECTOR_KEY_CVLAN] = sparx5_tc_flower_handler_cvlan_usage,
575 	[FLOW_DISSECTOR_KEY_VLAN] = sparx5_tc_flower_handler_vlan_usage,
576 	[FLOW_DISSECTOR_KEY_TCP] = sparx5_tc_flower_handler_tcp_usage,
577 	[FLOW_DISSECTOR_KEY_ARP] = sparx5_tc_flower_handler_arp_usage,
578 	[FLOW_DISSECTOR_KEY_IP] = sparx5_tc_flower_handler_ip_usage,
579 };
580 
581 static int sparx5_tc_use_dissectors(struct flow_cls_offload *fco,
582 				    struct vcap_admin *admin,
583 				    struct vcap_rule *vrule,
584 				    u16 *l3_proto)
585 {
586 	struct sparx5_tc_flower_parse_usage state = {
587 		.fco = fco,
588 		.vrule = vrule,
589 		.l3_proto = ETH_P_ALL,
590 		.admin = admin,
591 	};
592 	int idx, err = 0;
593 
594 	state.frule = flow_cls_offload_flow_rule(fco);
595 	for (idx = 0; idx < ARRAY_SIZE(sparx5_tc_flower_usage_handlers); ++idx) {
596 		if (!flow_rule_match_key(state.frule, idx))
597 			continue;
598 		if (!sparx5_tc_flower_usage_handlers[idx])
599 			continue;
600 		err = sparx5_tc_flower_usage_handlers[idx](&state);
601 		if (err)
602 			return err;
603 	}
604 
605 	if (state.frule->match.dissector->used_keys ^ state.used_keys) {
606 		NL_SET_ERR_MSG_MOD(fco->common.extack,
607 				   "Unsupported match item");
608 		return -ENOENT;
609 	}
610 
611 	if (l3_proto)
612 		*l3_proto = state.l3_proto;
613 	return err;
614 }
615 
616 static int sparx5_tc_flower_action_check(struct vcap_control *vctrl,
617 					 struct net_device *ndev,
618 					 struct flow_cls_offload *fco)
619 {
620 	struct flow_rule *rule = flow_cls_offload_flow_rule(fco);
621 	struct flow_action_entry *actent, *last_actent = NULL;
622 	struct flow_action *act = &rule->action;
623 	u64 action_mask = 0;
624 	int idx;
625 
626 	if (!flow_action_has_entries(act)) {
627 		NL_SET_ERR_MSG_MOD(fco->common.extack, "No actions");
628 		return -EINVAL;
629 	}
630 
631 	if (!flow_action_basic_hw_stats_check(act, fco->common.extack))
632 		return -EOPNOTSUPP;
633 
634 	flow_action_for_each(idx, actent, act) {
635 		if (action_mask & BIT(actent->id)) {
636 			NL_SET_ERR_MSG_MOD(fco->common.extack,
637 					   "More actions of the same type");
638 			return -EINVAL;
639 		}
640 		action_mask |= BIT(actent->id);
641 		last_actent = actent; /* Save last action for later check */
642 	}
643 
644 	/* Check if last action is a goto
645 	 * The last chain/lookup does not need to have a goto action
646 	 */
647 	if (last_actent->id == FLOW_ACTION_GOTO) {
648 		/* Check if the destination chain is in one of the VCAPs */
649 		if (!vcap_is_next_lookup(vctrl, fco->common.chain_index,
650 					 last_actent->chain_index)) {
651 			NL_SET_ERR_MSG_MOD(fco->common.extack,
652 					   "Invalid goto chain");
653 			return -EINVAL;
654 		}
655 	} else if (!vcap_is_last_chain(vctrl, fco->common.chain_index)) {
656 		NL_SET_ERR_MSG_MOD(fco->common.extack,
657 				   "Last action must be 'goto'");
658 		return -EINVAL;
659 	}
660 
661 	/* Catch unsupported combinations of actions */
662 	if (action_mask & BIT(FLOW_ACTION_TRAP) &&
663 	    action_mask & BIT(FLOW_ACTION_ACCEPT)) {
664 		NL_SET_ERR_MSG_MOD(fco->common.extack,
665 				   "Cannot combine pass and trap action");
666 		return -EOPNOTSUPP;
667 	}
668 
669 	return 0;
670 }
671 
672 /* Add a rule counter action */
673 static int sparx5_tc_add_rule_counter(struct vcap_admin *admin,
674 				      struct vcap_rule *vrule)
675 {
676 	int err;
677 
678 	if (admin->vtype == VCAP_TYPE_IS2) {
679 		err = vcap_rule_mod_action_u32(vrule, VCAP_AF_CNT_ID,
680 					       vrule->id);
681 		if (err)
682 			return err;
683 		vcap_rule_set_counter_id(vrule, vrule->id);
684 	}
685 
686 	return 0;
687 }
688 
689 /* Collect all port keysets and apply the first of them, possibly wildcarded */
690 static int sparx5_tc_select_protocol_keyset(struct net_device *ndev,
691 					    struct vcap_rule *vrule,
692 					    struct vcap_admin *admin,
693 					    u16 l3_proto,
694 					    struct sparx5_multiple_rules *multi)
695 {
696 	struct sparx5_port *port = netdev_priv(ndev);
697 	struct vcap_keyset_list portkeysetlist = {};
698 	enum vcap_keyfield_set portkeysets[10] = {};
699 	struct vcap_keyset_list matches = {};
700 	enum vcap_keyfield_set keysets[10];
701 	int idx, jdx, err = 0, count = 0;
702 	struct sparx5_wildcard_rule *mru;
703 	const struct vcap_set *kinfo;
704 	struct vcap_control *vctrl;
705 
706 	vctrl = port->sparx5->vcap_ctrl;
707 
708 	/* Find the keysets that the rule can use */
709 	matches.keysets = keysets;
710 	matches.max = ARRAY_SIZE(keysets);
711 	if (vcap_rule_find_keysets(vrule, &matches) == 0)
712 		return -EINVAL;
713 
714 	/* Find the keysets that the port configuration supports */
715 	portkeysetlist.max = ARRAY_SIZE(portkeysets);
716 	portkeysetlist.keysets = portkeysets;
717 	err = sparx5_vcap_get_port_keyset(ndev,
718 					  admin, vrule->vcap_chain_id,
719 					  l3_proto,
720 					  &portkeysetlist);
721 	if (err)
722 		return err;
723 
724 	/* Find the intersection of the two sets of keyset */
725 	for (idx = 0; idx < portkeysetlist.cnt; ++idx) {
726 		kinfo = vcap_keyfieldset(vctrl, admin->vtype,
727 					 portkeysetlist.keysets[idx]);
728 		if (!kinfo)
729 			continue;
730 
731 		/* Find a port keyset that matches the required keys
732 		 * If there are multiple keysets then compose a type id mask
733 		 */
734 		for (jdx = 0; jdx < matches.cnt; ++jdx) {
735 			if (portkeysetlist.keysets[idx] != matches.keysets[jdx])
736 				continue;
737 
738 			mru = &multi->rule[kinfo->sw_per_item];
739 			if (!mru->selected) {
740 				mru->selected = true;
741 				mru->keyset = portkeysetlist.keysets[idx];
742 				mru->value = kinfo->type_id;
743 			}
744 			mru->value &= kinfo->type_id;
745 			mru->mask |= kinfo->type_id;
746 			++count;
747 		}
748 	}
749 	if (count == 0)
750 		return -EPROTO;
751 
752 	if (l3_proto == ETH_P_ALL && count < portkeysetlist.cnt)
753 		return -ENOENT;
754 
755 	for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) {
756 		mru = &multi->rule[idx];
757 		if (!mru->selected)
758 			continue;
759 
760 		/* Align the mask to the combined value */
761 		mru->mask ^= mru->value;
762 	}
763 
764 	/* Set the chosen keyset on the rule and set a wildcarded type if there
765 	 * are more than one keyset
766 	 */
767 	for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) {
768 		mru = &multi->rule[idx];
769 		if (!mru->selected)
770 			continue;
771 
772 		vcap_set_rule_set_keyset(vrule, mru->keyset);
773 		if (count > 1)
774 			/* Some keysets do not have a type field */
775 			vcap_rule_mod_key_u32(vrule, VCAP_KF_TYPE,
776 					      mru->value,
777 					      ~mru->mask);
778 		mru->selected = false; /* mark as done */
779 		break; /* Stop here and add more rules later */
780 	}
781 	return err;
782 }
783 
784 static int sparx5_tc_add_rule_copy(struct vcap_control *vctrl,
785 				   struct flow_cls_offload *fco,
786 				   struct vcap_rule *erule,
787 				   struct vcap_admin *admin,
788 				   struct sparx5_wildcard_rule *rule)
789 {
790 	enum vcap_key_field keylist[] = {
791 		VCAP_KF_IF_IGR_PORT_MASK,
792 		VCAP_KF_IF_IGR_PORT_MASK_SEL,
793 		VCAP_KF_IF_IGR_PORT_MASK_RNG,
794 		VCAP_KF_LOOKUP_FIRST_IS,
795 		VCAP_KF_TYPE,
796 	};
797 	struct vcap_rule *vrule;
798 	int err;
799 
800 	/* Add an extra rule with a special user and the new keyset */
801 	erule->user = VCAP_USER_TC_EXTRA;
802 	vrule = vcap_copy_rule(erule);
803 	if (IS_ERR(vrule))
804 		return PTR_ERR(vrule);
805 
806 	/* Link the new rule to the existing rule with the cookie */
807 	vrule->cookie = erule->cookie;
808 	vcap_filter_rule_keys(vrule, keylist, ARRAY_SIZE(keylist), true);
809 	err = vcap_set_rule_set_keyset(vrule, rule->keyset);
810 	if (err) {
811 		pr_err("%s:%d: could not set keyset %s in rule: %u\n",
812 		       __func__, __LINE__,
813 		       vcap_keyset_name(vctrl, rule->keyset),
814 		       vrule->id);
815 		goto out;
816 	}
817 
818 	/* Some keysets do not have a type field, so ignore return value */
819 	vcap_rule_mod_key_u32(vrule, VCAP_KF_TYPE, rule->value, ~rule->mask);
820 
821 	err = vcap_set_rule_set_actionset(vrule, erule->actionset);
822 	if (err)
823 		goto out;
824 
825 	err = sparx5_tc_add_rule_counter(admin, vrule);
826 	if (err)
827 		goto out;
828 
829 	err = vcap_val_rule(vrule, ETH_P_ALL);
830 	if (err) {
831 		pr_err("%s:%d: could not validate rule: %u\n",
832 		       __func__, __LINE__, vrule->id);
833 		vcap_set_tc_exterr(fco, vrule);
834 		goto out;
835 	}
836 	err = vcap_add_rule(vrule);
837 	if (err) {
838 		pr_err("%s:%d: could not add rule: %u\n",
839 		       __func__, __LINE__, vrule->id);
840 		goto out;
841 	}
842 out:
843 	vcap_free_rule(vrule);
844 	return err;
845 }
846 
847 static int sparx5_tc_add_remaining_rules(struct vcap_control *vctrl,
848 					 struct flow_cls_offload *fco,
849 					 struct vcap_rule *erule,
850 					 struct vcap_admin *admin,
851 					 struct sparx5_multiple_rules *multi)
852 {
853 	int idx, err = 0;
854 
855 	for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) {
856 		if (!multi->rule[idx].selected)
857 			continue;
858 
859 		err = sparx5_tc_add_rule_copy(vctrl, fco, erule, admin,
860 					      &multi->rule[idx]);
861 		if (err)
862 			break;
863 	}
864 	return err;
865 }
866 
867 /* Add the actionset that is the default for the VCAP type */
868 static int sparx5_tc_set_actionset(struct vcap_admin *admin,
869 				   struct vcap_rule *vrule)
870 {
871 	enum vcap_actionfield_set aset;
872 	int err = 0;
873 
874 	switch (admin->vtype) {
875 	case VCAP_TYPE_IS0:
876 		aset = VCAP_AFS_CLASSIFICATION;
877 		break;
878 	case VCAP_TYPE_IS2:
879 		aset = VCAP_AFS_BASE_TYPE;
880 		break;
881 	default:
882 		return -EINVAL;
883 	}
884 	/* Do not overwrite any current actionset */
885 	if (vrule->actionset == VCAP_AFS_NO_VALUE)
886 		err = vcap_set_rule_set_actionset(vrule, aset);
887 	return err;
888 }
889 
890 /* Add the VCAP key to match on for a rule target value */
891 static int sparx5_tc_add_rule_link_target(struct vcap_admin *admin,
892 					  struct vcap_rule *vrule,
893 					  int target_cid)
894 {
895 	int link_val = target_cid % VCAP_CID_LOOKUP_SIZE;
896 	int err;
897 
898 	if (!link_val)
899 		return 0;
900 
901 	switch (admin->vtype) {
902 	case VCAP_TYPE_IS0:
903 		/* Add NXT_IDX key for chaining rules between IS0 instances */
904 		err = vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX_SEL,
905 					    1, /* enable */
906 					    ~0);
907 		if (err)
908 			return err;
909 		return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX,
910 					     link_val, /* target */
911 					     ~0);
912 	case VCAP_TYPE_IS2:
913 		/* Add PAG key for chaining rules from IS0 */
914 		return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG,
915 					     link_val, /* target */
916 					     ~0);
917 	default:
918 		break;
919 	}
920 	return 0;
921 }
922 
923 /* Add the VCAP action that adds a target value to a rule */
924 static int sparx5_tc_add_rule_link(struct vcap_control *vctrl,
925 				   struct vcap_admin *admin,
926 				   struct vcap_rule *vrule,
927 				   int from_cid, int to_cid)
928 {
929 	struct vcap_admin *to_admin = vcap_find_admin(vctrl, to_cid);
930 	int diff, err = 0;
931 
932 	diff = vcap_chain_offset(vctrl, from_cid, to_cid);
933 	if (!(to_admin && diff > 0)) {
934 		pr_err("%s:%d: unsupported chain direction: %d\n",
935 		       __func__, __LINE__, to_cid);
936 		return -EINVAL;
937 	}
938 	if (admin->vtype == VCAP_TYPE_IS0 &&
939 	    to_admin->vtype == VCAP_TYPE_IS0) {
940 		/* Between IS0 instances the G_IDX value is used */
941 		err = vcap_rule_add_action_u32(vrule, VCAP_AF_NXT_IDX, diff);
942 		if (err)
943 			goto out;
944 		err = vcap_rule_add_action_u32(vrule, VCAP_AF_NXT_IDX_CTRL,
945 					       1); /* Replace */
946 		if (err)
947 			goto out;
948 	} else if (admin->vtype == VCAP_TYPE_IS0 &&
949 		   to_admin->vtype == VCAP_TYPE_IS2) {
950 		/* Between IS0 and IS2 the PAG value is used */
951 		err = vcap_rule_add_action_u32(vrule, VCAP_AF_PAG_VAL, diff);
952 		if (err)
953 			goto out;
954 		err = vcap_rule_add_action_u32(vrule,
955 					       VCAP_AF_PAG_OVERRIDE_MASK,
956 					       0xff);
957 		if (err)
958 			goto out;
959 	} else {
960 		pr_err("%s:%d: unsupported chain destination: %d\n",
961 		       __func__, __LINE__, to_cid);
962 		err = -EOPNOTSUPP;
963 	}
964 out:
965 	return err;
966 }
967 
968 static int sparx5_tc_flower_replace(struct net_device *ndev,
969 				    struct flow_cls_offload *fco,
970 				    struct vcap_admin *admin)
971 {
972 	struct sparx5_port *port = netdev_priv(ndev);
973 	struct sparx5_multiple_rules multi = {};
974 	struct flow_action_entry *act;
975 	struct vcap_control *vctrl;
976 	struct flow_rule *frule;
977 	struct vcap_rule *vrule;
978 	u16 l3_proto;
979 	int err, idx;
980 
981 	vctrl = port->sparx5->vcap_ctrl;
982 
983 	err = sparx5_tc_flower_action_check(vctrl, ndev, fco);
984 	if (err)
985 		return err;
986 
987 	vrule = vcap_alloc_rule(vctrl, ndev, fco->common.chain_index, VCAP_USER_TC,
988 				fco->common.prio, 0);
989 	if (IS_ERR(vrule))
990 		return PTR_ERR(vrule);
991 
992 	vrule->cookie = fco->cookie;
993 
994 	l3_proto = ETH_P_ALL;
995 	err = sparx5_tc_use_dissectors(fco, admin, vrule, &l3_proto);
996 	if (err)
997 		goto out;
998 
999 	err = sparx5_tc_add_rule_counter(admin, vrule);
1000 	if (err)
1001 		goto out;
1002 
1003 	err = sparx5_tc_add_rule_link_target(admin, vrule,
1004 					     fco->common.chain_index);
1005 	if (err)
1006 		goto out;
1007 
1008 	frule = flow_cls_offload_flow_rule(fco);
1009 	flow_action_for_each(idx, act, &frule->action) {
1010 		switch (act->id) {
1011 		case FLOW_ACTION_TRAP:
1012 			if (admin->vtype != VCAP_TYPE_IS2) {
1013 				NL_SET_ERR_MSG_MOD(fco->common.extack,
1014 						   "Trap action not supported in this VCAP");
1015 				err = -EOPNOTSUPP;
1016 				goto out;
1017 			}
1018 			err = vcap_rule_add_action_bit(vrule,
1019 						       VCAP_AF_CPU_COPY_ENA,
1020 						       VCAP_BIT_1);
1021 			if (err)
1022 				goto out;
1023 			err = vcap_rule_add_action_u32(vrule,
1024 						       VCAP_AF_CPU_QUEUE_NUM, 0);
1025 			if (err)
1026 				goto out;
1027 			err = vcap_rule_add_action_u32(vrule, VCAP_AF_MASK_MODE,
1028 						       SPX5_PMM_REPLACE_ALL);
1029 			if (err)
1030 				goto out;
1031 			break;
1032 		case FLOW_ACTION_ACCEPT:
1033 			err = sparx5_tc_set_actionset(admin, vrule);
1034 			if (err)
1035 				goto out;
1036 			break;
1037 		case FLOW_ACTION_GOTO:
1038 			err = sparx5_tc_set_actionset(admin, vrule);
1039 			if (err)
1040 				goto out;
1041 			sparx5_tc_add_rule_link(vctrl, admin, vrule,
1042 						fco->common.chain_index,
1043 						act->chain_index);
1044 			break;
1045 		default:
1046 			NL_SET_ERR_MSG_MOD(fco->common.extack,
1047 					   "Unsupported TC action");
1048 			err = -EOPNOTSUPP;
1049 			goto out;
1050 		}
1051 	}
1052 
1053 	err = sparx5_tc_select_protocol_keyset(ndev, vrule, admin, l3_proto,
1054 					       &multi);
1055 	if (err) {
1056 		NL_SET_ERR_MSG_MOD(fco->common.extack,
1057 				   "No matching port keyset for filter protocol and keys");
1058 		goto out;
1059 	}
1060 
1061 	/* provide the l3 protocol to guide the keyset selection */
1062 	err = vcap_val_rule(vrule, l3_proto);
1063 	if (err) {
1064 		vcap_set_tc_exterr(fco, vrule);
1065 		goto out;
1066 	}
1067 	err = vcap_add_rule(vrule);
1068 	if (err)
1069 		NL_SET_ERR_MSG_MOD(fco->common.extack,
1070 				   "Could not add the filter");
1071 
1072 	if (l3_proto == ETH_P_ALL)
1073 		err = sparx5_tc_add_remaining_rules(vctrl, fco, vrule, admin,
1074 						    &multi);
1075 
1076 out:
1077 	vcap_free_rule(vrule);
1078 	return err;
1079 }
1080 
1081 static int sparx5_tc_flower_destroy(struct net_device *ndev,
1082 				    struct flow_cls_offload *fco,
1083 				    struct vcap_admin *admin)
1084 {
1085 	struct sparx5_port *port = netdev_priv(ndev);
1086 	struct vcap_control *vctrl;
1087 	int err = -ENOENT, rule_id;
1088 
1089 	vctrl = port->sparx5->vcap_ctrl;
1090 	while (true) {
1091 		rule_id = vcap_lookup_rule_by_cookie(vctrl, fco->cookie);
1092 		if (rule_id <= 0)
1093 			break;
1094 		err = vcap_del_rule(vctrl, ndev, rule_id);
1095 		if (err) {
1096 			pr_err("%s:%d: could not delete rule %d\n",
1097 			       __func__, __LINE__, rule_id);
1098 			break;
1099 		}
1100 	}
1101 	return err;
1102 }
1103 
1104 static int sparx5_tc_flower_stats(struct net_device *ndev,
1105 				  struct flow_cls_offload *fco,
1106 				  struct vcap_admin *admin)
1107 {
1108 	struct sparx5_port *port = netdev_priv(ndev);
1109 	struct vcap_counter ctr = {};
1110 	struct vcap_control *vctrl;
1111 	ulong lastused = 0;
1112 	int err;
1113 
1114 	vctrl = port->sparx5->vcap_ctrl;
1115 	err = vcap_get_rule_count_by_cookie(vctrl, &ctr, fco->cookie);
1116 	if (err)
1117 		return err;
1118 	flow_stats_update(&fco->stats, 0x0, ctr.value, 0, lastused,
1119 			  FLOW_ACTION_HW_STATS_IMMEDIATE);
1120 	return err;
1121 }
1122 
1123 int sparx5_tc_flower(struct net_device *ndev, struct flow_cls_offload *fco,
1124 		     bool ingress)
1125 {
1126 	struct sparx5_port *port = netdev_priv(ndev);
1127 	struct vcap_control *vctrl;
1128 	struct vcap_admin *admin;
1129 	int err = -EINVAL;
1130 
1131 	/* Get vcap instance from the chain id */
1132 	vctrl = port->sparx5->vcap_ctrl;
1133 	admin = vcap_find_admin(vctrl, fco->common.chain_index);
1134 	if (!admin) {
1135 		NL_SET_ERR_MSG_MOD(fco->common.extack, "Invalid chain");
1136 		return err;
1137 	}
1138 
1139 	switch (fco->command) {
1140 	case FLOW_CLS_REPLACE:
1141 		return sparx5_tc_flower_replace(ndev, fco, admin);
1142 	case FLOW_CLS_DESTROY:
1143 		return sparx5_tc_flower_destroy(ndev, fco, admin);
1144 	case FLOW_CLS_STATS:
1145 		return sparx5_tc_flower_stats(ndev, fco, admin);
1146 	default:
1147 		return -EOPNOTSUPP;
1148 	}
1149 }
1150