xref: /dpdk/drivers/net/ipn3ke/ipn3ke_flow.c (revision 85cf6dc3)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4 
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12 
13 #include <rte_io.h>
14 #include <rte_debug.h>
15 #include <rte_ether.h>
16 #include <rte_ethdev_driver.h>
17 #include <rte_log.h>
18 #include <rte_malloc.h>
19 #include <rte_eth_ctrl.h>
20 #include <rte_tailq.h>
21 
22 #include "ipn3ke_rawdev_api.h"
23 #include "ipn3ke_flow.h"
24 #include "ipn3ke_logs.h"
25 #include "ipn3ke_ethdev.h"
26 
27 /** Static initializer for items. */
28 #define FLOW_PATTERNS(...) \
29 	((const enum rte_flow_item_type []) { \
30 		__VA_ARGS__, RTE_FLOW_ITEM_TYPE_END, \
31 	})
32 
33 enum IPN3KE_HASH_KEY_TYPE {
34 	IPN3KE_HASH_KEY_VXLAN,
35 	IPN3KE_HASH_KEY_MAC,
36 	IPN3KE_HASH_KEY_QINQ,
37 	IPN3KE_HASH_KEY_MPLS,
38 	IPN3KE_HASH_KEY_IP_TCP,
39 	IPN3KE_HASH_KEY_IP_UDP,
40 	IPN3KE_HASH_KEY_IP_NVGRE,
41 	IPN3KE_HASH_KEY_VXLAN_IP_UDP,
42 };
43 
44 struct ipn3ke_flow_parse {
45 	uint32_t mark:1; /**< Set if the flow is marked. */
46 	uint32_t drop:1; /**< ACL drop. */
47 	uint32_t key_type:IPN3KE_FLOW_KEY_ID_BITS;
48 	uint32_t mark_id:IPN3KE_FLOW_RESULT_UID_BITS; /**< Mark identifier. */
49 	uint8_t key_len; /**< Length in bit. */
50 	uint8_t key[BITS_TO_BYTES(IPN3KE_FLOW_KEY_DATA_BITS)];
51 		/**< key1, key2 */
52 };
53 
54 typedef int (*pattern_filter_t)(const struct rte_flow_item patterns[],
55 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser);
56 
57 
58 struct ipn3ke_flow_pattern {
59 	const enum rte_flow_item_type *const items;
60 
61 	pattern_filter_t filter;
62 };
63 
64 /*
65  * @ RTL definition:
66  * typedef struct packed {
67  * logic [47:0]    vxlan_inner_mac;
68  * logic [23:0]    vxlan_vni;
69  * } Hash_Key_Vxlan_t;
70  *
71  * @ flow items:
72  * RTE_FLOW_ITEM_TYPE_VXLAN
73  * RTE_FLOW_ITEM_TYPE_ETH
74  */
75 static int
76 ipn3ke_pattern_vxlan(const struct rte_flow_item patterns[],
77 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
78 {
79 	const struct rte_flow_item_vxlan *vxlan = NULL;
80 	const struct rte_flow_item_eth *eth = NULL;
81 	const struct rte_flow_item *item;
82 
83 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
84 		if (/*!item->spec || item->mask || */item->last) {
85 			rte_flow_error_set(error,
86 					EINVAL,
87 					RTE_FLOW_ERROR_TYPE_ITEM,
88 					item,
89 					"Only support item with 'spec'");
90 			return -rte_errno;
91 		}
92 
93 		switch (item->type) {
94 		case RTE_FLOW_ITEM_TYPE_ETH:
95 			eth = item->spec;
96 
97 			rte_memcpy(&parser->key[0],
98 					eth->src.addr_bytes,
99 					RTE_ETHER_ADDR_LEN);
100 			break;
101 
102 		case RTE_FLOW_ITEM_TYPE_VXLAN:
103 			vxlan = item->spec;
104 
105 			rte_memcpy(&parser->key[6], vxlan->vni, 3);
106 			break;
107 
108 		default:
109 			rte_flow_error_set(error,
110 					EINVAL,
111 					RTE_FLOW_ERROR_TYPE_ITEM,
112 					item,
113 					"Not support item type");
114 			return -rte_errno;
115 		}
116 	}
117 
118 	if (vxlan != NULL && eth != NULL) {
119 		parser->key_len = 48 + 24;
120 		return 0;
121 	}
122 
123 	rte_flow_error_set(error,
124 			EINVAL,
125 			RTE_FLOW_ERROR_TYPE_ITEM,
126 			patterns,
127 			"Missed some patterns");
128 	return -rte_errno;
129 }
130 
131 /*
132  * @ RTL definition:
133  * typedef struct packed {
134  * logic [47:0]    eth_smac;
135  * } Hash_Key_Mac_t;
136  *
137  * @ flow items:
138  * RTE_FLOW_ITEM_TYPE_ETH
139  */
140 static int
141 ipn3ke_pattern_mac(const struct rte_flow_item patterns[],
142 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
143 {
144 	const struct rte_flow_item_eth *eth = NULL;
145 	const struct rte_flow_item *item;
146 
147 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
148 		if (!item->spec || item->mask || item->last) {
149 			rte_flow_error_set(error,
150 					EINVAL,
151 					RTE_FLOW_ERROR_TYPE_ITEM,
152 					item,
153 					"Only support item with 'spec'");
154 			return -rte_errno;
155 		}
156 
157 		switch (item->type) {
158 		case RTE_FLOW_ITEM_TYPE_ETH:
159 			eth = item->spec;
160 
161 			rte_memcpy(parser->key,
162 					eth->src.addr_bytes,
163 					RTE_ETHER_ADDR_LEN);
164 			break;
165 
166 		default:
167 			rte_flow_error_set(error,
168 					EINVAL,
169 					RTE_FLOW_ERROR_TYPE_ITEM,
170 					item,
171 					"Not support item type");
172 			return -rte_errno;
173 		}
174 	}
175 
176 	if (eth != NULL) {
177 		parser->key_len = 48;
178 		return 0;
179 	}
180 
181 	rte_flow_error_set(error,
182 			EINVAL,
183 			RTE_FLOW_ERROR_TYPE_ITEM,
184 			patterns,
185 			"Missed some patterns");
186 	return -rte_errno;
187 }
188 
189 /*
190  * @ RTL definition:
191  * typedef struct packed {
192  * logic [11:0]    outer_vlan_id;
193  * logic [11:0]    inner_vlan_id;
194  * } Hash_Key_QinQ_t;
195  *
196  * @ flow items:
197  * RTE_FLOW_ITEM_TYPE_VLAN
198  * RTE_FLOW_ITEM_TYPE_VLAN
199  */
200 static int
201 ipn3ke_pattern_qinq(const struct rte_flow_item patterns[],
202 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
203 {
204 	const struct rte_flow_item_vlan *outer_vlan = NULL;
205 	const struct rte_flow_item_vlan *inner_vlan = NULL;
206 	const struct rte_flow_item *item;
207 	uint16_t tci;
208 
209 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
210 		if (!item->spec || item->mask || item->last) {
211 			rte_flow_error_set(error,
212 					EINVAL,
213 					RTE_FLOW_ERROR_TYPE_ITEM,
214 					item,
215 					"Only support item with 'spec'");
216 			return -rte_errno;
217 		}
218 
219 		switch (item->type) {
220 		case RTE_FLOW_ITEM_TYPE_VLAN:
221 			if (!outer_vlan) {
222 				outer_vlan = item->spec;
223 
224 				tci = rte_be_to_cpu_16(outer_vlan->tci);
225 				parser->key[0]  = (tci & 0xff0) >> 4;
226 				parser->key[1] |= (tci & 0x00f) << 4;
227 			} else {
228 				inner_vlan = item->spec;
229 
230 				tci = rte_be_to_cpu_16(inner_vlan->tci);
231 				parser->key[1] |= (tci & 0xf00) >> 8;
232 				parser->key[2]  = (tci & 0x0ff);
233 			}
234 			break;
235 
236 		default:
237 			rte_flow_error_set(error,
238 					EINVAL,
239 					RTE_FLOW_ERROR_TYPE_ITEM,
240 					item,
241 					"Not support item type");
242 			return -rte_errno;
243 		}
244 	}
245 
246 	if (outer_vlan != NULL && inner_vlan != NULL) {
247 		parser->key_len = 12 + 12;
248 		return 0;
249 	}
250 
251 	rte_flow_error_set(error,
252 			EINVAL,
253 			RTE_FLOW_ERROR_TYPE_ITEM,
254 			patterns,
255 			"Missed some patterns");
256 	return -rte_errno;
257 }
258 
259 /*
260  * @ RTL definition:
261  * typedef struct packed {
262  * logic [19:0]    mpls_label1;
263  * logic [19:0]    mpls_label2;
264  * } Hash_Key_Mpls_t;
265  *
266  * @ flow items:
267  * RTE_FLOW_ITEM_TYPE_MPLS
268  * RTE_FLOW_ITEM_TYPE_MPLS
269  */
270 static int
271 ipn3ke_pattern_mpls(const struct rte_flow_item patterns[],
272 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
273 {
274 	const struct rte_flow_item_mpls *mpls1 = NULL;
275 	const struct rte_flow_item_mpls *mpls2 = NULL;
276 	const struct rte_flow_item *item;
277 
278 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
279 		if (!item->spec || item->mask || item->last) {
280 			rte_flow_error_set(error,
281 					EINVAL,
282 					RTE_FLOW_ERROR_TYPE_ITEM,
283 					item,
284 					"Only support item with 'spec'");
285 			return -rte_errno;
286 		}
287 
288 		switch (item->type) {
289 		case RTE_FLOW_ITEM_TYPE_MPLS:
290 			if (!mpls1) {
291 				mpls1 = item->spec;
292 
293 				parser->key[0] = mpls1->label_tc_s[0];
294 				parser->key[1] = mpls1->label_tc_s[1];
295 				parser->key[2] = mpls1->label_tc_s[2] & 0xf0;
296 			} else {
297 				mpls2 = item->spec;
298 
299 				parser->key[2] |=
300 					((mpls2->label_tc_s[0] & 0xf0) >> 4);
301 				parser->key[3] =
302 					((mpls2->label_tc_s[0] & 0xf) << 4) |
303 					((mpls2->label_tc_s[1] & 0xf0) >> 4);
304 				parser->key[4] =
305 					((mpls2->label_tc_s[1] & 0xf) << 4) |
306 					((mpls2->label_tc_s[2] & 0xf0) >> 4);
307 			}
308 			break;
309 
310 		default:
311 			rte_flow_error_set(error,
312 					EINVAL,
313 					RTE_FLOW_ERROR_TYPE_ITEM,
314 					item,
315 					"Not support item type");
316 			return -rte_errno;
317 		}
318 	}
319 
320 	if (mpls1 != NULL && mpls2 != NULL) {
321 		parser->key_len = 20 + 20;
322 		return 0;
323 	}
324 
325 	rte_flow_error_set(error,
326 			EINVAL,
327 			RTE_FLOW_ERROR_TYPE_ITEM,
328 			patterns,
329 			"Missed some patterns");
330 	return -rte_errno;
331 }
332 
333 /*
334  * @ RTL definition:
335  * typedef struct packed {
336  * logic [31:0]    ip_sa;
337  * logic [15:0]    tcp_sport;
338  * } Hash_Key_Ip_Tcp_t;
339  *
340  * @ flow items:
341  * RTE_FLOW_ITEM_TYPE_IPV4
342  * RTE_FLOW_ITEM_TYPE_TCP
343  */
344 static int
345 ipn3ke_pattern_ip_tcp(const struct rte_flow_item patterns[],
346 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
347 {
348 	const struct rte_flow_item_ipv4 *ipv4 = NULL;
349 	const struct rte_flow_item_tcp *tcp = NULL;
350 	const struct rte_flow_item *item;
351 
352 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
353 		if (!item->spec || item->mask || item->last) {
354 			rte_flow_error_set(error,
355 					EINVAL,
356 					RTE_FLOW_ERROR_TYPE_ITEM,
357 					item,
358 					"Only support item with 'spec'");
359 			return -rte_errno;
360 		}
361 
362 		switch (item->type) {
363 		case RTE_FLOW_ITEM_TYPE_IPV4:
364 			ipv4 = item->spec;
365 
366 			rte_memcpy(&parser->key[0], &ipv4->hdr.src_addr, 4);
367 			break;
368 
369 		case RTE_FLOW_ITEM_TYPE_TCP:
370 			tcp = item->spec;
371 
372 			rte_memcpy(&parser->key[4], &tcp->hdr.src_port, 2);
373 			break;
374 
375 		default:
376 			rte_flow_error_set(error,
377 					EINVAL,
378 					RTE_FLOW_ERROR_TYPE_ITEM,
379 					item,
380 					"Not support item type");
381 			return -rte_errno;
382 		}
383 	}
384 
385 	if (ipv4 != NULL && tcp != NULL) {
386 		parser->key_len = 32 + 16;
387 		return 0;
388 	}
389 
390 	rte_flow_error_set(error,
391 			EINVAL,
392 			RTE_FLOW_ERROR_TYPE_ITEM,
393 			patterns,
394 			"Missed some patterns");
395 	return -rte_errno;
396 }
397 
398 /*
399  * @ RTL definition:
400  * typedef struct packed {
401  * logic [31:0]    ip_sa;
402  * logic [15:0]    udp_sport;
403  * } Hash_Key_Ip_Udp_t;
404  *
405  * @ flow items:
406  * RTE_FLOW_ITEM_TYPE_IPV4
407  * RTE_FLOW_ITEM_TYPE_UDP
408  */
409 static int
410 ipn3ke_pattern_ip_udp(const struct rte_flow_item patterns[],
411 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
412 {
413 	const struct rte_flow_item_ipv4 *ipv4 = NULL;
414 	const struct rte_flow_item_udp *udp = NULL;
415 	const struct rte_flow_item *item;
416 
417 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
418 		if (!item->spec || item->mask || item->last) {
419 			rte_flow_error_set(error,
420 					EINVAL,
421 					RTE_FLOW_ERROR_TYPE_ITEM,
422 					item,
423 					"Only support item with 'spec'");
424 			return -rte_errno;
425 		}
426 
427 		switch (item->type) {
428 		case RTE_FLOW_ITEM_TYPE_IPV4:
429 			ipv4 = item->spec;
430 
431 			rte_memcpy(&parser->key[0], &ipv4->hdr.src_addr, 4);
432 			break;
433 
434 		case RTE_FLOW_ITEM_TYPE_UDP:
435 			udp = item->spec;
436 
437 			rte_memcpy(&parser->key[4], &udp->hdr.src_port, 2);
438 			break;
439 
440 		default:
441 			rte_flow_error_set(error,
442 					EINVAL,
443 					RTE_FLOW_ERROR_TYPE_ITEM,
444 					item,
445 					"Not support item type");
446 			return -rte_errno;
447 		}
448 	}
449 
450 	if (ipv4 != NULL && udp != NULL) {
451 		parser->key_len = 32 + 16;
452 		return 0;
453 	}
454 
455 	rte_flow_error_set(error,
456 			EINVAL,
457 			RTE_FLOW_ERROR_TYPE_ITEM,
458 			patterns,
459 			"Missed some patterns");
460 	return -rte_errno;
461 }
462 
463 /*
464  * @ RTL definition:
465  * typedef struct packed {
466  * logic [31:0]    ip_sa;
467  * logic [15:0]    udp_sport;
468  * logic [23:0]    vsid;
469  * } Hash_Key_Ip_Nvgre_t;
470  *
471  * @ flow items:
472  * RTE_FLOW_ITEM_TYPE_IPV4
473  * RTE_FLOW_ITEM_TYPE_UDP
474  * RTE_FLOW_ITEM_TYPE_NVGRE
475  */
476 static int
477 ipn3ke_pattern_ip_nvgre(const struct rte_flow_item patterns[],
478 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
479 {
480 	const struct rte_flow_item_nvgre *nvgre = NULL;
481 	const struct rte_flow_item_ipv4 *ipv4 = NULL;
482 	const struct rte_flow_item_udp *udp = NULL;
483 	const struct rte_flow_item *item;
484 
485 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
486 		if (!item->spec || item->mask || item->last) {
487 			rte_flow_error_set(error,
488 					EINVAL,
489 					RTE_FLOW_ERROR_TYPE_ITEM,
490 					item,
491 					"Only support item with 'spec'");
492 			return -rte_errno;
493 		}
494 
495 		switch (item->type) {
496 		case RTE_FLOW_ITEM_TYPE_IPV4:
497 			ipv4 = item->spec;
498 
499 			rte_memcpy(&parser->key[0], &ipv4->hdr.src_addr, 4);
500 			break;
501 
502 		case RTE_FLOW_ITEM_TYPE_UDP:
503 			udp = item->spec;
504 
505 			rte_memcpy(&parser->key[4], &udp->hdr.src_port, 2);
506 			break;
507 
508 		case RTE_FLOW_ITEM_TYPE_NVGRE:
509 			nvgre = item->spec;
510 
511 			rte_memcpy(&parser->key[6], nvgre->tni, 3);
512 			break;
513 
514 		default:
515 			rte_flow_error_set(error,
516 					EINVAL,
517 					RTE_FLOW_ERROR_TYPE_ITEM,
518 					item,
519 					"Not support item type");
520 			return -rte_errno;
521 		}
522 	}
523 
524 	if (ipv4 != NULL && udp != NULL && nvgre != NULL) {
525 		parser->key_len = 32 + 16 + 24;
526 		return 0;
527 	}
528 
529 	rte_flow_error_set(error,
530 			EINVAL,
531 			RTE_FLOW_ERROR_TYPE_ITEM,
532 			patterns,
533 			"Missed some patterns");
534 	return -rte_errno;
535 }
536 
537 /*
538  * @ RTL definition:
539  * typedef struct packed{
540  * logic [23:0]    vxlan_vni;
541  * logic [31:0]    ip_sa;
542  * logic [15:0]    udp_sport;
543  * } Hash_Key_Vxlan_Ip_Udp_t;
544  *
545  * @ flow items:
546  * RTE_FLOW_ITEM_TYPE_VXLAN
547  * RTE_FLOW_ITEM_TYPE_IPV4
548  * RTE_FLOW_ITEM_TYPE_UDP
549  */
550 static int
551 ipn3ke_pattern_vxlan_ip_udp(const struct rte_flow_item patterns[],
552 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
553 {
554 	const struct rte_flow_item_vxlan *vxlan = NULL;
555 	const struct rte_flow_item_ipv4 *ipv4 = NULL;
556 	const struct rte_flow_item_udp *udp = NULL;
557 	const struct rte_flow_item *item;
558 
559 	for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
560 		if (!item->spec || item->mask || item->last) {
561 			rte_flow_error_set(error,
562 					EINVAL,
563 					RTE_FLOW_ERROR_TYPE_ITEM,
564 					item,
565 					"Only support item with 'spec'");
566 			return -rte_errno;
567 		}
568 
569 		switch (item->type) {
570 		case RTE_FLOW_ITEM_TYPE_VXLAN:
571 			vxlan = item->spec;
572 
573 			rte_memcpy(&parser->key[0], vxlan->vni, 3);
574 			break;
575 
576 		case RTE_FLOW_ITEM_TYPE_IPV4:
577 			ipv4 = item->spec;
578 
579 			rte_memcpy(&parser->key[3], &ipv4->hdr.src_addr, 4);
580 			break;
581 
582 		case RTE_FLOW_ITEM_TYPE_UDP:
583 			udp = item->spec;
584 
585 			rte_memcpy(&parser->key[7], &udp->hdr.src_port, 2);
586 			break;
587 
588 		default:
589 			rte_flow_error_set(error,
590 					EINVAL,
591 					RTE_FLOW_ERROR_TYPE_ITEM,
592 					item,
593 					"Not support item type");
594 			return -rte_errno;
595 		}
596 	}
597 
598 	if (vxlan != NULL && ipv4 != NULL && udp != NULL) {
599 		parser->key_len = 24 + 32 + 16;
600 		return 0;
601 	}
602 
603 	rte_flow_error_set(error,
604 			EINVAL,
605 			RTE_FLOW_ERROR_TYPE_ITEM,
606 			patterns,
607 			"Missed some patterns");
608 	return -rte_errno;
609 }
610 
611 static const struct ipn3ke_flow_pattern ipn3ke_supported_patterns[] = {
612 	[IPN3KE_HASH_KEY_VXLAN] = {
613 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_VXLAN,
614 					RTE_FLOW_ITEM_TYPE_ETH),
615 		.filter = ipn3ke_pattern_vxlan,
616 	},
617 
618 	[IPN3KE_HASH_KEY_MAC] = {
619 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_ETH),
620 		.filter = ipn3ke_pattern_mac,
621 	},
622 
623 	[IPN3KE_HASH_KEY_QINQ] = {
624 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_VLAN,
625 					RTE_FLOW_ITEM_TYPE_VLAN),
626 		.filter = ipn3ke_pattern_qinq,
627 	},
628 
629 	[IPN3KE_HASH_KEY_MPLS] = {
630 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_MPLS,
631 					RTE_FLOW_ITEM_TYPE_MPLS),
632 		.filter = ipn3ke_pattern_mpls,
633 	},
634 
635 	[IPN3KE_HASH_KEY_IP_TCP] = {
636 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_IPV4,
637 					RTE_FLOW_ITEM_TYPE_TCP),
638 		.filter = ipn3ke_pattern_ip_tcp,
639 	},
640 
641 	[IPN3KE_HASH_KEY_IP_UDP] = {
642 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_IPV4,
643 					RTE_FLOW_ITEM_TYPE_UDP),
644 		.filter = ipn3ke_pattern_ip_udp,
645 	},
646 
647 	[IPN3KE_HASH_KEY_IP_NVGRE] = {
648 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_IPV4,
649 					RTE_FLOW_ITEM_TYPE_UDP,
650 					RTE_FLOW_ITEM_TYPE_NVGRE),
651 		.filter = ipn3ke_pattern_ip_nvgre,
652 	},
653 
654 	[IPN3KE_HASH_KEY_VXLAN_IP_UDP] = {
655 		.items = FLOW_PATTERNS(RTE_FLOW_ITEM_TYPE_VXLAN,
656 					RTE_FLOW_ITEM_TYPE_IPV4,
657 					RTE_FLOW_ITEM_TYPE_UDP),
658 		.filter = ipn3ke_pattern_vxlan_ip_udp,
659 	},
660 };
661 
662 static int
663 ipn3ke_flow_convert_attributes(const struct rte_flow_attr *attr,
664 				struct rte_flow_error *error)
665 {
666 	if (!attr) {
667 		rte_flow_error_set(error,
668 				EINVAL,
669 				RTE_FLOW_ERROR_TYPE_ATTR,
670 				NULL,
671 				"NULL attribute.");
672 		return -rte_errno;
673 	}
674 
675 	if (attr->group) {
676 		rte_flow_error_set(error,
677 				ENOTSUP,
678 				RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
679 				NULL,
680 				"groups are not supported");
681 		return -rte_errno;
682 	}
683 
684 	if (attr->egress) {
685 		rte_flow_error_set(error,
686 				ENOTSUP,
687 				RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
688 				NULL,
689 				"egress is not supported");
690 		return -rte_errno;
691 	}
692 
693 	if (attr->transfer) {
694 		rte_flow_error_set(error,
695 				ENOTSUP,
696 				RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
697 				NULL,
698 				"transfer is not supported");
699 		return -rte_errno;
700 	}
701 
702 	if (!attr->ingress) {
703 		rte_flow_error_set(error,
704 				ENOTSUP,
705 				RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
706 				NULL,
707 				"only ingress is supported");
708 		return -rte_errno;
709 	}
710 
711 	return 0;
712 }
713 
714 static int
715 ipn3ke_flow_convert_actions(const struct rte_flow_action actions[],
716 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
717 {
718 	const struct rte_flow_action_mark *mark = NULL;
719 
720 	if (!actions) {
721 		rte_flow_error_set(error,
722 				EINVAL,
723 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
724 				NULL,
725 				"NULL action.");
726 		return -rte_errno;
727 	}
728 
729 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
730 		switch (actions->type) {
731 		case RTE_FLOW_ACTION_TYPE_VOID:
732 			break;
733 
734 		case RTE_FLOW_ACTION_TYPE_MARK:
735 			if (mark) {
736 				rte_flow_error_set(error,
737 						ENOTSUP,
738 						RTE_FLOW_ERROR_TYPE_ACTION,
739 						actions,
740 						"duplicated mark");
741 				return -rte_errno;
742 			}
743 
744 			mark = actions->conf;
745 			if (!mark) {
746 				rte_flow_error_set(error,
747 						EINVAL,
748 						RTE_FLOW_ERROR_TYPE_ACTION,
749 						actions,
750 						"mark must be defined");
751 				return -rte_errno;
752 			} else if (mark->id > IPN3KE_FLOW_RESULT_UID_MAX) {
753 				rte_flow_error_set(error,
754 						ENOTSUP,
755 						RTE_FLOW_ERROR_TYPE_ACTION,
756 						actions,
757 						"mark id is out of range");
758 				return -rte_errno;
759 			}
760 
761 			parser->mark = 1;
762 			parser->mark_id = mark->id;
763 			break;
764 
765 		case RTE_FLOW_ACTION_TYPE_DROP:
766 			parser->drop = 1;
767 			break;
768 
769 		default:
770 			rte_flow_error_set(error,
771 					ENOTSUP,
772 					RTE_FLOW_ERROR_TYPE_ACTION,
773 					actions,
774 					"invalid action");
775 			return -rte_errno;
776 		}
777 	}
778 
779 	if (!parser->drop && !parser->mark) {
780 		rte_flow_error_set(error,
781 				EINVAL,
782 				RTE_FLOW_ERROR_TYPE_ACTION,
783 				actions,
784 				"no valid actions");
785 		return -rte_errno;
786 	}
787 
788 	return 0;
789 }
790 
791 static bool
792 ipn3ke_match_pattern(const enum rte_flow_item_type *patterns,
793 				const struct rte_flow_item *input)
794 {
795 	const struct rte_flow_item *item = input;
796 
797 	while ((*patterns == item->type) &&
798 		(*patterns != RTE_FLOW_ITEM_TYPE_END)) {
799 		patterns++;
800 		item++;
801 	}
802 
803 	return (*patterns == RTE_FLOW_ITEM_TYPE_END &&
804 		item->type == RTE_FLOW_ITEM_TYPE_END);
805 }
806 
807 static pattern_filter_t
808 ipn3ke_find_filter_func(const struct rte_flow_item *input,
809 				uint32_t *idx)
810 {
811 	pattern_filter_t filter = NULL;
812 	uint32_t i;
813 
814 	for (i = 0; i < RTE_DIM(ipn3ke_supported_patterns); i++) {
815 		if (ipn3ke_match_pattern(ipn3ke_supported_patterns[i].items,
816 					input)) {
817 			filter = ipn3ke_supported_patterns[i].filter;
818 			*idx = i;
819 			break;
820 		}
821 	}
822 
823 	return filter;
824 }
825 
826 static int
827 ipn3ke_flow_convert_items(const struct rte_flow_item items[],
828 	struct rte_flow_error *error, struct ipn3ke_flow_parse *parser)
829 {
830 	pattern_filter_t filter = NULL;
831 	uint32_t idx;
832 
833 	if (!items) {
834 		rte_flow_error_set(error,
835 				EINVAL,
836 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
837 				NULL,
838 				"NULL pattern.");
839 		return -rte_errno;
840 	}
841 
842 	filter = ipn3ke_find_filter_func(items, &idx);
843 
844 	if (!filter) {
845 		rte_flow_error_set(error,
846 				EINVAL,
847 				RTE_FLOW_ERROR_TYPE_ITEM,
848 				items,
849 				"Unsupported pattern");
850 		return -rte_errno;
851 	}
852 
853 	parser->key_type = idx;
854 
855 	return filter(items, error, parser);
856 }
857 
858 /* Put the least @nbits of @data into @offset of @dst bits stream, and
859  * the @offset starts from MSB to LSB in each byte.
860  *
861  * MSB    LSB
862  *  +------+------+------+------+
863  *  |      |      |      |      |
864  *  +------+------+------+------+
865  *       ^                 ^
866  *       |<- data: nbits ->|
867  *       |
868  *     offset
869  */
870 static void
871 copy_data_bits(uint8_t *dst, uint64_t data,
872 		uint32_t offset, uint8_t nbits)
873 {
874 	uint8_t set, *p = &dst[offset / BITS_PER_BYTE];
875 	uint8_t bits_to_set = BITS_PER_BYTE - (offset % BITS_PER_BYTE);
876 	uint8_t mask_to_set = 0xff >> (offset % BITS_PER_BYTE);
877 	uint32_t size = offset + nbits;
878 
879 	if (nbits > (sizeof(data) * BITS_PER_BYTE)) {
880 		IPN3KE_AFU_PMD_ERR("nbits is out of range");
881 		return;
882 	}
883 
884 	while (nbits - bits_to_set >= 0) {
885 		set = data >> (nbits - bits_to_set);
886 
887 		*p &= ~mask_to_set;
888 		*p |= (set & mask_to_set);
889 
890 		nbits -= bits_to_set;
891 		bits_to_set = BITS_PER_BYTE;
892 		mask_to_set = 0xff;
893 		p++;
894 	}
895 
896 	if (nbits) {
897 		uint8_t shift = BITS_PER_BYTE - (size % BITS_PER_BYTE);
898 
899 		set = data << shift;
900 		mask_to_set = 0xff << shift;
901 
902 		*p &= ~mask_to_set;
903 		*p |= (set & mask_to_set);
904 	}
905 }
906 
907 static void
908 ipn3ke_flow_key_generation(struct ipn3ke_flow_parse *parser,
909 				struct rte_flow *flow)
910 {
911 	uint32_t i, shift_bytes, len_in_bytes, offset;
912 	uint64_t key;
913 	uint8_t *dst;
914 
915 	dst = flow->rule.key;
916 
917 	copy_data_bits(dst,
918 			parser->key_type,
919 			IPN3KE_FLOW_KEY_ID_OFFSET,
920 			IPN3KE_FLOW_KEY_ID_BITS);
921 
922 	/* The MSb of key is filled to 0 when it is less than
923 	 * IPN3KE_FLOW_KEY_DATA_BITS bit. And the parsed key data is
924 	 * save as MSB byte first in the array, it needs to move
925 	 * the bits before formatting them.
926 	 */
927 	key = 0;
928 	shift_bytes = 0;
929 	len_in_bytes = BITS_TO_BYTES(parser->key_len);
930 	offset = (IPN3KE_FLOW_KEY_DATA_OFFSET +
931 		IPN3KE_FLOW_KEY_DATA_BITS -
932 		parser->key_len);
933 
934 	for (i = 0; i < len_in_bytes; i++) {
935 		key = (key << 8) | parser->key[i];
936 
937 		if (++shift_bytes == sizeof(key)) {
938 			shift_bytes = 0;
939 
940 			copy_data_bits(dst, key, offset,
941 					sizeof(key) * BITS_PER_BYTE);
942 			offset += sizeof(key) * BITS_PER_BYTE;
943 			key = 0;
944 		}
945 	}
946 
947 	if (shift_bytes != 0) {
948 		uint32_t rem_bits;
949 
950 		rem_bits = parser->key_len % (sizeof(key) * BITS_PER_BYTE);
951 		key >>= (shift_bytes * 8 - rem_bits);
952 		copy_data_bits(dst, key, offset, rem_bits);
953 	}
954 }
955 
956 static void
957 ipn3ke_flow_result_generation(struct ipn3ke_flow_parse *parser,
958 				struct rte_flow *flow)
959 {
960 	uint8_t *dst;
961 
962 	if (parser->drop)
963 		return;
964 
965 	dst = flow->rule.result;
966 
967 	copy_data_bits(dst,
968 			1,
969 			IPN3KE_FLOW_RESULT_ACL_OFFSET,
970 			IPN3KE_FLOW_RESULT_ACL_BITS);
971 
972 	copy_data_bits(dst,
973 			parser->mark_id,
974 			IPN3KE_FLOW_RESULT_UID_OFFSET,
975 			IPN3KE_FLOW_RESULT_UID_BITS);
976 }
977 
978 #define MHL_COMMAND_TIME_COUNT        0xFFFF
979 #define MHL_COMMAND_TIME_INTERVAL_US  10
980 
981 static int
982 ipn3ke_flow_hw_update(struct ipn3ke_hw *hw,
983 			struct rte_flow *flow, uint32_t is_add)
984 {
985 	uint32_t *pdata = NULL;
986 	uint32_t data;
987 	uint32_t time_out = MHL_COMMAND_TIME_COUNT;
988 	uint32_t i;
989 
990 	IPN3KE_AFU_PMD_DEBUG("IPN3KE flow dump start\n");
991 
992 	pdata = (uint32_t *)flow->rule.key;
993 	IPN3KE_AFU_PMD_DEBUG(" - key   :");
994 
995 	for (i = 0; i < RTE_DIM(flow->rule.key); i++)
996 		IPN3KE_AFU_PMD_DEBUG(" %02x", flow->rule.key[i]);
997 
998 	for (i = 0; i < 4; i++)
999 		IPN3KE_AFU_PMD_DEBUG(" %02x", ipn3ke_swap32(pdata[3 - i]));
1000 	IPN3KE_AFU_PMD_DEBUG("\n");
1001 
1002 	pdata = (uint32_t *)flow->rule.result;
1003 	IPN3KE_AFU_PMD_DEBUG(" - result:");
1004 
1005 	for (i = 0; i < RTE_DIM(flow->rule.result); i++)
1006 		IPN3KE_AFU_PMD_DEBUG(" %02x", flow->rule.result[i]);
1007 
1008 	for (i = 0; i < 1; i++)
1009 		IPN3KE_AFU_PMD_DEBUG(" %02x", pdata[i]);
1010 	IPN3KE_AFU_PMD_DEBUG("IPN3KE flow dump end\n");
1011 
1012 	pdata = (uint32_t *)flow->rule.key;
1013 
1014 	IPN3KE_MASK_WRITE_REG(hw,
1015 			IPN3KE_CLF_MHL_KEY_0,
1016 			0,
1017 			ipn3ke_swap32(pdata[3]),
1018 			IPN3KE_CLF_MHL_KEY_MASK);
1019 
1020 	IPN3KE_MASK_WRITE_REG(hw,
1021 			IPN3KE_CLF_MHL_KEY_1,
1022 			0,
1023 			ipn3ke_swap32(pdata[2]),
1024 			IPN3KE_CLF_MHL_KEY_MASK);
1025 
1026 	IPN3KE_MASK_WRITE_REG(hw,
1027 			IPN3KE_CLF_MHL_KEY_2,
1028 			0,
1029 			ipn3ke_swap32(pdata[1]),
1030 			IPN3KE_CLF_MHL_KEY_MASK);
1031 
1032 	IPN3KE_MASK_WRITE_REG(hw,
1033 			IPN3KE_CLF_MHL_KEY_3,
1034 			0,
1035 			ipn3ke_swap32(pdata[0]),
1036 			IPN3KE_CLF_MHL_KEY_MASK);
1037 
1038 	pdata = (uint32_t *)flow->rule.result;
1039 	IPN3KE_MASK_WRITE_REG(hw,
1040 			IPN3KE_CLF_MHL_RES,
1041 			0,
1042 			ipn3ke_swap32(pdata[0]),
1043 			IPN3KE_CLF_MHL_RES_MASK);
1044 
1045 	/* insert/delete the key and result */
1046 	data = 0;
1047 	data = IPN3KE_MASK_READ_REG(hw,
1048 				IPN3KE_CLF_MHL_MGMT_CTRL,
1049 				0,
1050 				0x80000000);
1051 	time_out = MHL_COMMAND_TIME_COUNT;
1052 	while (IPN3KE_BIT_ISSET(data, IPN3KE_CLF_MHL_MGMT_CTRL_BIT_BUSY) &&
1053 		(time_out > 0)) {
1054 		data = IPN3KE_MASK_READ_REG(hw,
1055 					IPN3KE_CLF_MHL_MGMT_CTRL,
1056 					0,
1057 					0x80000000);
1058 		time_out--;
1059 		rte_delay_us(MHL_COMMAND_TIME_INTERVAL_US);
1060 	}
1061 	if (!time_out)
1062 		return -1;
1063 	if (is_add)
1064 		IPN3KE_MASK_WRITE_REG(hw,
1065 				IPN3KE_CLF_MHL_MGMT_CTRL,
1066 				0,
1067 				IPN3KE_CLF_MHL_MGMT_CTRL_INSERT,
1068 				0x3);
1069 	else
1070 		IPN3KE_MASK_WRITE_REG(hw,
1071 				IPN3KE_CLF_MHL_MGMT_CTRL,
1072 				0,
1073 				IPN3KE_CLF_MHL_MGMT_CTRL_DELETE,
1074 				0x3);
1075 
1076 	return 0;
1077 }
1078 
1079 static int
1080 ipn3ke_flow_hw_flush(struct ipn3ke_hw *hw)
1081 {
1082 	uint32_t data;
1083 	uint32_t time_out = MHL_COMMAND_TIME_COUNT;
1084 
1085 	/* flush the MHL lookup table */
1086 	data = 0;
1087 	data = IPN3KE_MASK_READ_REG(hw,
1088 				IPN3KE_CLF_MHL_MGMT_CTRL,
1089 				0,
1090 				0x80000000);
1091 	time_out = MHL_COMMAND_TIME_COUNT;
1092 	while (IPN3KE_BIT_ISSET(data, IPN3KE_CLF_MHL_MGMT_CTRL_BIT_BUSY) &&
1093 		(time_out > 0)) {
1094 		data = IPN3KE_MASK_READ_REG(hw,
1095 					IPN3KE_CLF_MHL_MGMT_CTRL,
1096 					0,
1097 					0x80000000);
1098 		time_out--;
1099 		rte_delay_us(MHL_COMMAND_TIME_INTERVAL_US);
1100 	}
1101 	if (!time_out)
1102 		return -1;
1103 	IPN3KE_MASK_WRITE_REG(hw,
1104 			IPN3KE_CLF_MHL_MGMT_CTRL,
1105 			0,
1106 			IPN3KE_CLF_MHL_MGMT_CTRL_FLUSH,
1107 			0x3);
1108 
1109 	return 0;
1110 }
1111 
1112 static void
1113 ipn3ke_flow_convert_finalise(struct ipn3ke_hw *hw,
1114 	struct ipn3ke_flow_parse *parser, struct rte_flow *flow)
1115 {
1116 	ipn3ke_flow_key_generation(parser, flow);
1117 	ipn3ke_flow_result_generation(parser, flow);
1118 	ipn3ke_flow_hw_update(hw, flow, 1);
1119 }
1120 
1121 static int
1122 ipn3ke_flow_convert(const struct rte_flow_attr *attr,
1123 	const struct rte_flow_item items[],
1124 	const struct rte_flow_action actions[], struct rte_flow_error *error,
1125 	struct ipn3ke_flow_parse *parser)
1126 {
1127 	int ret;
1128 
1129 	ret = ipn3ke_flow_convert_attributes(attr, error);
1130 	if (ret)
1131 		return ret;
1132 
1133 	ret = ipn3ke_flow_convert_actions(actions, error, parser);
1134 	if (ret)
1135 		return ret;
1136 
1137 	ret = ipn3ke_flow_convert_items(items, error, parser);
1138 	if (ret)
1139 		return ret;
1140 
1141 	return 0;
1142 }
1143 
1144 static int
1145 ipn3ke_flow_validate(__rte_unused struct rte_eth_dev *dev,
1146 	const struct rte_flow_attr *attr, const struct rte_flow_item pattern[],
1147 	const struct rte_flow_action actions[], struct rte_flow_error *error)
1148 {
1149 	struct ipn3ke_flow_parse parser = {0};
1150 	return ipn3ke_flow_convert(attr, pattern, actions, error, &parser);
1151 }
1152 
1153 static struct rte_flow *
1154 ipn3ke_flow_create(struct rte_eth_dev *dev,
1155 	const struct rte_flow_attr *attr, const struct rte_flow_item pattern[],
1156 	const struct rte_flow_action actions[], struct rte_flow_error *error)
1157 {
1158 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1159 	struct ipn3ke_flow_parse parser = {0};
1160 	struct rte_flow *flow;
1161 	int ret;
1162 
1163 	if (hw->flow_num_entries == hw->flow_max_entries) {
1164 		rte_flow_error_set(error,
1165 				ENOBUFS,
1166 				RTE_FLOW_ERROR_TYPE_HANDLE,
1167 				NULL,
1168 				"The flow table is full.");
1169 		return NULL;
1170 	}
1171 
1172 	ret = ipn3ke_flow_convert(attr, pattern, actions, error, &parser);
1173 	if (ret < 0) {
1174 		rte_flow_error_set(error,
1175 				-ret,
1176 				RTE_FLOW_ERROR_TYPE_HANDLE,
1177 				NULL,
1178 				"Failed to create flow.");
1179 		return NULL;
1180 	}
1181 
1182 	flow = rte_zmalloc("ipn3ke_flow", sizeof(struct rte_flow), 0);
1183 	if (!flow) {
1184 		rte_flow_error_set(error,
1185 				ENOMEM,
1186 				RTE_FLOW_ERROR_TYPE_HANDLE,
1187 				NULL,
1188 				"Failed to allocate memory");
1189 		return flow;
1190 	}
1191 
1192 	ipn3ke_flow_convert_finalise(hw, &parser, flow);
1193 
1194 	TAILQ_INSERT_TAIL(&hw->flow_list, flow, next);
1195 
1196 	return flow;
1197 }
1198 
1199 static int
1200 ipn3ke_flow_destroy(struct rte_eth_dev *dev,
1201 	struct rte_flow *flow, struct rte_flow_error *error)
1202 {
1203 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1204 	int ret = 0;
1205 
1206 	ret = ipn3ke_flow_hw_update(hw, flow, 0);
1207 	if (!ret) {
1208 		TAILQ_REMOVE(&hw->flow_list, flow, next);
1209 		rte_free(flow);
1210 	} else {
1211 		rte_flow_error_set(error,
1212 				-ret,
1213 				RTE_FLOW_ERROR_TYPE_HANDLE,
1214 				NULL,
1215 				"Failed to destroy flow.");
1216 	}
1217 
1218 	return ret;
1219 }
1220 
1221 static int
1222 ipn3ke_flow_flush(struct rte_eth_dev *dev,
1223 		__rte_unused struct rte_flow_error *error)
1224 {
1225 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1226 	struct rte_flow *flow, *temp;
1227 
1228 	TAILQ_FOREACH_SAFE(flow, &hw->flow_list, next, temp) {
1229 		TAILQ_REMOVE(&hw->flow_list, flow, next);
1230 		rte_free(flow);
1231 	}
1232 
1233 	return ipn3ke_flow_hw_flush(hw);
1234 }
1235 
1236 int ipn3ke_flow_init(void *dev)
1237 {
1238 	struct ipn3ke_hw *hw = (struct ipn3ke_hw *)dev;
1239 	uint32_t data;
1240 
1241 	/* disable rx classifier bypass */
1242 	IPN3KE_MASK_WRITE_REG(hw,
1243 			IPN3KE_CLF_RX_TEST,
1244 			0, 0, 0x1);
1245 
1246 	data = 0;
1247 	data = IPN3KE_MASK_READ_REG(hw,
1248 				IPN3KE_CLF_RX_TEST,
1249 				0,
1250 				0x1);
1251 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_RX_TEST: %x\n", data);
1252 
1253 	/* configure base mac address */
1254 	IPN3KE_MASK_WRITE_REG(hw,
1255 			IPN3KE_CLF_BASE_DST_MAC_ADDR_HI,
1256 			0,
1257 			0x2457,
1258 			0xFFFF);
1259 
1260 	data = 0;
1261 	data = IPN3KE_MASK_READ_REG(hw,
1262 				IPN3KE_CLF_BASE_DST_MAC_ADDR_HI,
1263 				0,
1264 				0xFFFF);
1265 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_BASE_DST_MAC_ADDR_HI: %x\n", data);
1266 
1267 	IPN3KE_MASK_WRITE_REG(hw,
1268 			IPN3KE_CLF_BASE_DST_MAC_ADDR_LOW,
1269 			0,
1270 			0x9bdf1000,
1271 			0xFFFFFFFF);
1272 
1273 	data = 0;
1274 	data = IPN3KE_MASK_READ_REG(hw,
1275 				IPN3KE_CLF_BASE_DST_MAC_ADDR_LOW,
1276 				0,
1277 				0xFFFFFFFF);
1278 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_BASE_DST_MAC_ADDR_LOW: %x\n", data);
1279 
1280 
1281 	/* configure hash lookup rules enable */
1282 	IPN3KE_MASK_WRITE_REG(hw,
1283 			IPN3KE_CLF_LKUP_ENABLE,
1284 			0,
1285 			0xFD,
1286 			0xFF);
1287 
1288 	data = 0;
1289 	data = IPN3KE_MASK_READ_REG(hw,
1290 				IPN3KE_CLF_LKUP_ENABLE,
1291 				0,
1292 				0xFF);
1293 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_LKUP_ENABLE: %x\n", data);
1294 
1295 
1296 	/* configure rx parse config, settings associatied with VxLAN */
1297 	IPN3KE_MASK_WRITE_REG(hw,
1298 			IPN3KE_CLF_RX_PARSE_CFG,
1299 			0,
1300 			0x212b5,
1301 			0x3FFFF);
1302 
1303 	data = 0;
1304 	data = IPN3KE_MASK_READ_REG(hw,
1305 				IPN3KE_CLF_RX_PARSE_CFG,
1306 				0,
1307 				0x3FFFF);
1308 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_RX_PARSE_CFG: %x\n", data);
1309 
1310 
1311 	/* configure QinQ S-Tag */
1312 	IPN3KE_MASK_WRITE_REG(hw,
1313 			IPN3KE_CLF_QINQ_STAG,
1314 			0,
1315 			0x88a8,
1316 			0xFFFF);
1317 
1318 	data = 0;
1319 	data = IPN3KE_MASK_READ_REG(hw,
1320 				IPN3KE_CLF_QINQ_STAG,
1321 				0,
1322 				0xFFFF);
1323 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_QINQ_STAG: %x\n", data);
1324 
1325 
1326 	/* configure gen ctrl */
1327 	IPN3KE_MASK_WRITE_REG(hw,
1328 			IPN3KE_CLF_MHL_GEN_CTRL,
1329 			0,
1330 			0x3,
1331 			0x3);
1332 
1333 	data = 0;
1334 	data = IPN3KE_MASK_READ_REG(hw,
1335 				IPN3KE_CLF_MHL_GEN_CTRL,
1336 				0,
1337 				0x1F);
1338 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_MHL_GEN_CTRL: %x\n", data);
1339 
1340 
1341 	/* clear monitoring register */
1342 	IPN3KE_MASK_WRITE_REG(hw,
1343 			IPN3KE_CLF_MHL_MON_0,
1344 			0,
1345 			0xFFFFFFFF,
1346 			0xFFFFFFFF);
1347 
1348 	data = 0;
1349 	data = IPN3KE_MASK_READ_REG(hw,
1350 				IPN3KE_CLF_MHL_MON_0,
1351 				0,
1352 				0xFFFFFFFF);
1353 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_MHL_MON_0: %x\n", data);
1354 
1355 
1356 	ipn3ke_flow_hw_flush(hw);
1357 
1358 	TAILQ_INIT(&hw->flow_list);
1359 	hw->flow_max_entries = IPN3KE_MASK_READ_REG(hw,
1360 						IPN3KE_CLF_EM_NUM,
1361 						0,
1362 						0xFFFFFFFF);
1363 	IPN3KE_AFU_PMD_DEBUG("IPN3KE_CLF_EN_NUM: %x\n", hw->flow_max_entries);
1364 	hw->flow_num_entries = 0;
1365 
1366 	return 0;
1367 }
1368 
1369 const struct rte_flow_ops ipn3ke_flow_ops = {
1370 	.validate = ipn3ke_flow_validate,
1371 	.create = ipn3ke_flow_create,
1372 	.destroy = ipn3ke_flow_destroy,
1373 	.flush = ipn3ke_flow_flush,
1374 };
1375 
1376