net/mlx5: add VLAN push/pop DR commands to glue
[dpdk.git] / drivers / net / ipn3ke / ipn3ke_flow.c
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 };