net/dpaa2: support generic flow
[dpdk.git] / drivers / net / dpaa2 / dpaa2_flow.c
1 /* * SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright 2018 NXP
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_ethdev.h>
14 #include <rte_log.h>
15 #include <rte_eth_ctrl.h>
16 #include <rte_malloc.h>
17 #include <rte_flow_driver.h>
18 #include <rte_tailq.h>
19
20 #include <fsl_dpni.h>
21 #include <fsl_dpkg.h>
22
23 #include <dpaa2_ethdev.h>
24 #include <dpaa2_pmd_logs.h>
25
26 struct rte_flow {
27         struct dpni_rule_cfg rule;
28         uint8_t key_size;
29         uint8_t tc_id;
30         uint8_t flow_type;
31         uint8_t index;
32         enum rte_flow_action_type action;
33         uint16_t flow_id;
34 };
35
36 /* Layout for rule compositions for supported patterns */
37 /* TODO: Current design only supports Ethernet + IPv4 based classification. */
38 /* So corresponding offset macros are valid only. Rest are placeholder for */
39 /* now. Once support for other netwrok headers will be added then */
40 /* corresponding macros will be updated with correct values*/
41 #define DPAA2_CLS_RULE_OFFSET_ETH       0       /*Start of buffer*/
42 #define DPAA2_CLS_RULE_OFFSET_VLAN      14      /* DPAA2_CLS_RULE_OFFSET_ETH */
43                                                 /*      + Sizeof Eth fields  */
44 #define DPAA2_CLS_RULE_OFFSET_IPV4      14      /* DPAA2_CLS_RULE_OFFSET_VLAN */
45                                                 /*      + Sizeof VLAN fields */
46 #define DPAA2_CLS_RULE_OFFSET_IPV6      25      /* DPAA2_CLS_RULE_OFFSET_IPV4 */
47                                                 /*      + Sizeof IPV4 fields */
48 #define DPAA2_CLS_RULE_OFFSET_ICMP      58      /* DPAA2_CLS_RULE_OFFSET_IPV6 */
49                                                 /*      + Sizeof IPV6 fields */
50 #define DPAA2_CLS_RULE_OFFSET_UDP       60      /* DPAA2_CLS_RULE_OFFSET_ICMP */
51                                                 /*      + Sizeof ICMP fields */
52 #define DPAA2_CLS_RULE_OFFSET_TCP       64      /* DPAA2_CLS_RULE_OFFSET_UDP  */
53                                                 /*      + Sizeof UDP fields  */
54 #define DPAA2_CLS_RULE_OFFSET_SCTP      68      /* DPAA2_CLS_RULE_OFFSET_TCP  */
55                                                 /*      + Sizeof TCP fields  */
56 #define DPAA2_CLS_RULE_OFFSET_GRE       72      /* DPAA2_CLS_RULE_OFFSET_SCTP */
57                                                 /*      + Sizeof SCTP fields */
58
59 static const
60 enum rte_flow_item_type dpaa2_supported_pattern_type[] = {
61         RTE_FLOW_ITEM_TYPE_END,
62         RTE_FLOW_ITEM_TYPE_ETH,
63         RTE_FLOW_ITEM_TYPE_VLAN,
64         RTE_FLOW_ITEM_TYPE_IPV4,
65         RTE_FLOW_ITEM_TYPE_IPV6,
66         RTE_FLOW_ITEM_TYPE_ICMP,
67         RTE_FLOW_ITEM_TYPE_UDP,
68         RTE_FLOW_ITEM_TYPE_TCP,
69         RTE_FLOW_ITEM_TYPE_SCTP,
70         RTE_FLOW_ITEM_TYPE_GRE,
71 };
72
73 static const
74 enum rte_flow_action_type dpaa2_supported_action_type[] = {
75         RTE_FLOW_ACTION_TYPE_END,
76         RTE_FLOW_ACTION_TYPE_QUEUE,
77         RTE_FLOW_ACTION_TYPE_RSS
78 };
79
80 enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE;
81 static const void *default_mask;
82
83 static int
84 dpaa2_configure_flow_eth(struct rte_flow *flow,
85                          struct rte_eth_dev *dev,
86                          const struct rte_flow_attr *attr,
87                          const struct rte_flow_item *pattern,
88                          const struct rte_flow_action actions[] __rte_unused,
89                          struct rte_flow_error *error __rte_unused)
90 {
91         int index, j = 0;
92         size_t key_iova;
93         size_t mask_iova;
94         int device_configured = 0, entry_found = 0;
95         uint32_t group;
96         const struct rte_flow_item_eth *spec, *mask;
97
98         /* TODO: Currently upper bound of range parameter is not implemented */
99         const struct rte_flow_item_eth *last __rte_unused;
100         struct dpaa2_dev_priv *priv = dev->data->dev_private;
101
102         group = attr->group;
103
104         /* DPAA2 platform has a limitation that extract parameter can not be */
105         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
106         /* TODO: pattern is an array of 9 elements where 9th pattern element */
107         /* is for QoS table and 1-8th pattern element is for FS tables. */
108         /* It can be changed to macro. */
109         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
110                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
111                                                 DPKG_MAX_NUM_OF_EXTRACTS);
112                 return -ENOTSUP;
113         }
114
115         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
116                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
117                                                 DPKG_MAX_NUM_OF_EXTRACTS);
118                 return -ENOTSUP;
119         }
120
121         for (j = 0; j < priv->pattern[8].item_count; j++) {
122                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
123                         continue;
124                 } else {
125                         entry_found = 1;
126                         break;
127                 }
128         }
129
130         if (!entry_found) {
131                 priv->pattern[8].pattern_type[j] = pattern->type;
132                 priv->pattern[8].item_count++;
133                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
134         }
135
136         entry_found = 0;
137         for (j = 0; j < priv->pattern[group].item_count; j++) {
138                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
139                         continue;
140                 } else {
141                         entry_found = 1;
142                         break;
143                 }
144         }
145
146         if (!entry_found) {
147                 priv->pattern[group].pattern_type[j] = pattern->type;
148                 priv->pattern[group].item_count++;
149                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
150         }
151
152         /* Get traffic class index and flow id to be configured */
153         flow->tc_id = group;
154         flow->index = attr->priority;
155
156         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
157                 index = priv->extract.qos_key_cfg.num_extracts;
158                 priv->extract.qos_key_cfg.extracts[index].type =
159                                                         DPKG_EXTRACT_FROM_HDR;
160                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
161                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
162                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA;
163                 index++;
164
165                 priv->extract.qos_key_cfg.extracts[index].type =
166                                                         DPKG_EXTRACT_FROM_HDR;
167                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
168                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
169                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA;
170                 index++;
171
172                 priv->extract.qos_key_cfg.extracts[index].type =
173                                                         DPKG_EXTRACT_FROM_HDR;
174                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
175                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
176                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE;
177                 index++;
178
179                 priv->extract.qos_key_cfg.num_extracts = index;
180         }
181
182         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
183                 index = priv->extract.fs_key_cfg[group].num_extracts;
184                 priv->extract.fs_key_cfg[group].extracts[index].type =
185                                                         DPKG_EXTRACT_FROM_HDR;
186                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
187                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
188                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA;
189                 index++;
190
191                 priv->extract.fs_key_cfg[group].extracts[index].type =
192                                                         DPKG_EXTRACT_FROM_HDR;
193                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
194                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
195                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA;
196                 index++;
197
198                 priv->extract.fs_key_cfg[group].extracts[index].type =
199                                                         DPKG_EXTRACT_FROM_HDR;
200                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
201                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH;
202                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE;
203                 index++;
204
205                 priv->extract.fs_key_cfg[group].num_extracts = index;
206         }
207
208         /* Parse pattern list to get the matching parameters */
209         spec    = (const struct rte_flow_item_eth *)pattern->spec;
210         last    = (const struct rte_flow_item_eth *)pattern->last;
211         mask    = (const struct rte_flow_item_eth *)
212                         (pattern->mask ? pattern->mask : default_mask);
213
214         /* Key rule */
215         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ETH;
216         memcpy((void *)key_iova, (const void *)(spec->src.addr_bytes),
217                                                 sizeof(struct ether_addr));
218         key_iova += sizeof(struct ether_addr);
219         memcpy((void *)key_iova, (const void *)(spec->dst.addr_bytes),
220                                                 sizeof(struct ether_addr));
221         key_iova += sizeof(struct ether_addr);
222         memcpy((void *)key_iova, (const void *)(&spec->type),
223                                                 sizeof(rte_be16_t));
224
225         /* Key mask */
226         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ETH;
227         memcpy((void *)mask_iova, (const void *)(mask->src.addr_bytes),
228                                                 sizeof(struct ether_addr));
229         mask_iova += sizeof(struct ether_addr);
230         memcpy((void *)mask_iova, (const void *)(mask->dst.addr_bytes),
231                                                 sizeof(struct ether_addr));
232         mask_iova += sizeof(struct ether_addr);
233         memcpy((void *)mask_iova, (const void *)(&mask->type),
234                                                 sizeof(rte_be16_t));
235
236         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ETH +
237                                 ((2  * sizeof(struct ether_addr)) +
238                                 sizeof(rte_be16_t)));
239         return device_configured;
240 }
241
242 static int
243 dpaa2_configure_flow_vlan(struct rte_flow *flow,
244                           struct rte_eth_dev *dev,
245                           const struct rte_flow_attr *attr,
246                           const struct rte_flow_item *pattern,
247                           const struct rte_flow_action actions[] __rte_unused,
248                           struct rte_flow_error *error __rte_unused)
249 {
250         int index, j = 0;
251         size_t key_iova;
252         size_t mask_iova;
253         int device_configured = 0, entry_found = 0;
254         uint32_t group;
255         const struct rte_flow_item_vlan *spec, *mask;
256
257         const struct rte_flow_item_vlan *last __rte_unused;
258         struct dpaa2_dev_priv *priv = dev->data->dev_private;
259
260         group = attr->group;
261
262         /* DPAA2 platform has a limitation that extract parameter can not be */
263         /*  more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
264         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
265                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
266                                                 DPKG_MAX_NUM_OF_EXTRACTS);
267                 return -ENOTSUP;
268         }
269
270         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
271                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
272                                                 DPKG_MAX_NUM_OF_EXTRACTS);
273                 return -ENOTSUP;
274         }
275
276         for (j = 0; j < priv->pattern[8].item_count; j++) {
277                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
278                         continue;
279                 } else {
280                         entry_found = 1;
281                         break;
282                 }
283         }
284
285         if (!entry_found) {
286                 priv->pattern[8].pattern_type[j] = pattern->type;
287                 priv->pattern[8].item_count++;
288                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
289         }
290
291         entry_found = 0;
292         for (j = 0; j < priv->pattern[group].item_count; j++) {
293                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
294                         continue;
295                 } else {
296                         entry_found = 1;
297                         break;
298                 }
299         }
300
301         if (!entry_found) {
302                 priv->pattern[group].pattern_type[j] = pattern->type;
303                 priv->pattern[group].item_count++;
304                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
305         }
306
307
308         /* Get traffic class index and flow id to be configured */
309         flow->tc_id = group;
310         flow->index = attr->priority;
311
312         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
313                 index = priv->extract.qos_key_cfg.num_extracts;
314                 priv->extract.qos_key_cfg.extracts[index].type =
315                                                         DPKG_EXTRACT_FROM_HDR;
316                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
317                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_VLAN;
318                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI;
319                 priv->extract.qos_key_cfg.num_extracts++;
320         }
321
322         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
323                 index = priv->extract.fs_key_cfg[group].num_extracts;
324                 priv->extract.fs_key_cfg[group].extracts[index].type =
325                                                         DPKG_EXTRACT_FROM_HDR;
326                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
327                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_VLAN;
328                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI;
329                 priv->extract.fs_key_cfg[group].num_extracts++;
330         }
331
332         /* Parse pattern list to get the matching parameters */
333         spec    = (const struct rte_flow_item_vlan *)pattern->spec;
334         last    = (const struct rte_flow_item_vlan *)pattern->last;
335         mask    = (const struct rte_flow_item_vlan *)
336                         (pattern->mask ? pattern->mask : default_mask);
337
338         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_VLAN;
339         memcpy((void *)key_iova, (const void *)(&spec->tci),
340                                                         sizeof(rte_be16_t));
341
342         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_VLAN;
343         memcpy((void *)mask_iova, (const void *)(&mask->tci),
344                                                         sizeof(rte_be16_t));
345
346         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_VLAN + sizeof(rte_be16_t));
347         return device_configured;
348 }
349
350 static int
351 dpaa2_configure_flow_ipv4(struct rte_flow *flow,
352                           struct rte_eth_dev *dev,
353                           const struct rte_flow_attr *attr,
354                           const struct rte_flow_item *pattern,
355                           const struct rte_flow_action actions[] __rte_unused,
356                           struct rte_flow_error *error __rte_unused)
357 {
358         int index, j = 0;
359         size_t key_iova;
360         size_t mask_iova;
361         int device_configured = 0, entry_found = 0;
362         uint32_t group;
363         const struct rte_flow_item_ipv4 *spec, *mask;
364
365         const struct rte_flow_item_ipv4 *last __rte_unused;
366         struct dpaa2_dev_priv *priv = dev->data->dev_private;
367
368         group = attr->group;
369
370         /* DPAA2 platform has a limitation that extract parameter can not be */
371         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
372         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
373                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
374                                                 DPKG_MAX_NUM_OF_EXTRACTS);
375                 return -ENOTSUP;
376         }
377
378         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
379                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
380                                                 DPKG_MAX_NUM_OF_EXTRACTS);
381                 return -ENOTSUP;
382         }
383
384         for (j = 0; j < priv->pattern[8].item_count; j++) {
385                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
386                         continue;
387                 } else {
388                         entry_found = 1;
389                         break;
390                 }
391         }
392
393         if (!entry_found) {
394                 priv->pattern[8].pattern_type[j] = pattern->type;
395                 priv->pattern[8].item_count++;
396                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
397         }
398
399         entry_found = 0;
400         for (j = 0; j < priv->pattern[group].item_count; j++) {
401                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
402                         continue;
403                 } else {
404                         entry_found = 1;
405                         break;
406                 }
407         }
408
409         if (!entry_found) {
410                 priv->pattern[group].pattern_type[j] = pattern->type;
411                 priv->pattern[group].item_count++;
412                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
413         }
414
415         /* Get traffic class index and flow id to be configured */
416         flow->tc_id = group;
417         flow->index = attr->priority;
418
419         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
420                 index = priv->extract.qos_key_cfg.num_extracts;
421                 priv->extract.qos_key_cfg.extracts[index].type =
422                                                         DPKG_EXTRACT_FROM_HDR;
423                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
424                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
425                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC;
426                 index++;
427
428                 priv->extract.qos_key_cfg.extracts[index].type =
429                                                         DPKG_EXTRACT_FROM_HDR;
430                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
431                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
432                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST;
433                 index++;
434
435                 priv->extract.qos_key_cfg.extracts[index].type =
436                                                         DPKG_EXTRACT_FROM_HDR;
437                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
438                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
439                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
440                 index++;
441
442                 priv->extract.qos_key_cfg.num_extracts = index;
443         }
444
445         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
446                 index = priv->extract.fs_key_cfg[group].num_extracts;
447                 priv->extract.fs_key_cfg[group].extracts[index].type =
448                                                         DPKG_EXTRACT_FROM_HDR;
449                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
450                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
451                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC;
452                 index++;
453
454                 priv->extract.fs_key_cfg[group].extracts[index].type =
455                                                         DPKG_EXTRACT_FROM_HDR;
456                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
457                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
458                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST;
459                 index++;
460
461                 priv->extract.fs_key_cfg[group].extracts[index].type =
462                                                         DPKG_EXTRACT_FROM_HDR;
463                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
464                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
465                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
466                 index++;
467
468                 priv->extract.fs_key_cfg[group].num_extracts = index;
469         }
470
471         /* Parse pattern list to get the matching parameters */
472         spec    = (const struct rte_flow_item_ipv4 *)pattern->spec;
473         last    = (const struct rte_flow_item_ipv4 *)pattern->last;
474         mask    = (const struct rte_flow_item_ipv4 *)
475                         (pattern->mask ? pattern->mask : default_mask);
476
477         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4;
478         memcpy((void *)key_iova, (const void *)&spec->hdr.src_addr,
479                                                         sizeof(uint32_t));
480         key_iova += sizeof(uint32_t);
481         memcpy((void *)key_iova, (const void *)&spec->hdr.dst_addr,
482                                                         sizeof(uint32_t));
483         key_iova += sizeof(uint32_t);
484         memcpy((void *)key_iova, (const void *)&spec->hdr.next_proto_id,
485                                                         sizeof(uint8_t));
486
487         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV4;
488         memcpy((void *)mask_iova, (const void *)&mask->hdr.src_addr,
489                                                         sizeof(uint32_t));
490         mask_iova += sizeof(uint32_t);
491         memcpy((void *)mask_iova, (const void *)&mask->hdr.dst_addr,
492                                                         sizeof(uint32_t));
493         mask_iova += sizeof(uint32_t);
494         memcpy((void *)mask_iova, (const void *)&mask->hdr.next_proto_id,
495                                                         sizeof(uint8_t));
496
497         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV4 +
498                                 (2 * sizeof(uint32_t)) + sizeof(uint8_t));
499
500         return device_configured;
501 }
502
503 static int
504 dpaa2_configure_flow_ipv6(struct rte_flow *flow,
505                           struct rte_eth_dev *dev,
506                           const struct rte_flow_attr *attr,
507                           const struct rte_flow_item *pattern,
508                           const struct rte_flow_action actions[] __rte_unused,
509                           struct rte_flow_error *error __rte_unused)
510 {
511         int index, j = 0;
512         size_t key_iova;
513         size_t mask_iova;
514         int device_configured = 0, entry_found = 0;
515         uint32_t group;
516         const struct rte_flow_item_ipv6 *spec, *mask;
517
518         const struct rte_flow_item_ipv6 *last __rte_unused;
519         struct dpaa2_dev_priv *priv = dev->data->dev_private;
520
521         group = attr->group;
522
523         /* DPAA2 platform has a limitation that extract parameter can not be */
524         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
525         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
526                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
527                                                 DPKG_MAX_NUM_OF_EXTRACTS);
528                 return -ENOTSUP;
529         }
530
531         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
532                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
533                                                 DPKG_MAX_NUM_OF_EXTRACTS);
534                 return -ENOTSUP;
535         }
536
537         for (j = 0; j < priv->pattern[8].item_count; j++) {
538                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
539                         continue;
540                 } else {
541                         entry_found = 1;
542                         break;
543                 }
544         }
545
546         if (!entry_found) {
547                 priv->pattern[8].pattern_type[j] = pattern->type;
548                 priv->pattern[8].item_count++;
549                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
550         }
551
552         entry_found = 0;
553         for (j = 0; j < priv->pattern[group].item_count; j++) {
554                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
555                         continue;
556                 } else {
557                         entry_found = 1;
558                         break;
559                 }
560         }
561
562         if (!entry_found) {
563                 priv->pattern[group].pattern_type[j] = pattern->type;
564                 priv->pattern[group].item_count++;
565                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
566         }
567
568         /* Get traffic class index and flow id to be configured */
569         flow->tc_id = group;
570         flow->index = attr->priority;
571
572         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
573                 index = priv->extract.qos_key_cfg.num_extracts;
574                 priv->extract.qos_key_cfg.extracts[index].type =
575                                                         DPKG_EXTRACT_FROM_HDR;
576                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
577                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
578                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC;
579                 index++;
580
581                 priv->extract.qos_key_cfg.extracts[index].type =
582                                                         DPKG_EXTRACT_FROM_HDR;
583                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
584                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
585                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST;
586                 index++;
587
588                 priv->extract.qos_key_cfg.num_extracts = index;
589         }
590
591         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
592                 index = priv->extract.fs_key_cfg[group].num_extracts;
593                 priv->extract.fs_key_cfg[group].extracts[index].type =
594                                                         DPKG_EXTRACT_FROM_HDR;
595                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
596                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
597                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC;
598                 index++;
599
600                 priv->extract.fs_key_cfg[group].extracts[index].type =
601                                                         DPKG_EXTRACT_FROM_HDR;
602                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
603                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
604                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST;
605                 index++;
606
607                 priv->extract.fs_key_cfg[group].num_extracts = index;
608         }
609
610         /* Parse pattern list to get the matching parameters */
611         spec    = (const struct rte_flow_item_ipv6 *)pattern->spec;
612         last    = (const struct rte_flow_item_ipv6 *)pattern->last;
613         mask    = (const struct rte_flow_item_ipv6 *)
614                         (pattern->mask ? pattern->mask : default_mask);
615
616         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV6;
617         memcpy((void *)key_iova, (const void *)(spec->hdr.src_addr),
618                                                 sizeof(spec->hdr.src_addr));
619         key_iova += sizeof(spec->hdr.src_addr);
620         memcpy((void *)key_iova, (const void *)(spec->hdr.dst_addr),
621                                                 sizeof(spec->hdr.dst_addr));
622
623         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV6;
624         memcpy((void *)mask_iova, (const void *)(mask->hdr.src_addr),
625                                                 sizeof(mask->hdr.src_addr));
626         mask_iova += sizeof(mask->hdr.src_addr);
627         memcpy((void *)mask_iova, (const void *)(mask->hdr.dst_addr),
628                                                 sizeof(mask->hdr.dst_addr));
629
630         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV6 +
631                                         sizeof(spec->hdr.src_addr) +
632                                         sizeof(mask->hdr.dst_addr));
633         return device_configured;
634 }
635
636 static int
637 dpaa2_configure_flow_icmp(struct rte_flow *flow,
638                           struct rte_eth_dev *dev,
639                           const struct rte_flow_attr *attr,
640                           const struct rte_flow_item *pattern,
641                           const struct rte_flow_action actions[] __rte_unused,
642                           struct rte_flow_error *error __rte_unused)
643 {
644         int index, j = 0;
645         size_t key_iova;
646         size_t mask_iova;
647         int device_configured = 0, entry_found = 0;
648         uint32_t group;
649         const struct rte_flow_item_icmp *spec, *mask;
650
651         const struct rte_flow_item_icmp *last __rte_unused;
652         struct dpaa2_dev_priv *priv = dev->data->dev_private;
653
654         group = attr->group;
655
656         /* DPAA2 platform has a limitation that extract parameter can not be */
657         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
658         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
659                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
660                                                 DPKG_MAX_NUM_OF_EXTRACTS);
661                 return -ENOTSUP;
662         }
663
664         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
665                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
666                                                 DPKG_MAX_NUM_OF_EXTRACTS);
667                 return -ENOTSUP;
668         }
669
670         for (j = 0; j < priv->pattern[8].item_count; j++) {
671                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
672                         continue;
673                 } else {
674                         entry_found = 1;
675                         break;
676                 }
677         }
678
679         if (!entry_found) {
680                 priv->pattern[8].pattern_type[j] = pattern->type;
681                 priv->pattern[8].item_count++;
682                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
683         }
684
685         entry_found = 0;
686         for (j = 0; j < priv->pattern[group].item_count; j++) {
687                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
688                         continue;
689                 } else {
690                         entry_found = 1;
691                         break;
692                 }
693         }
694
695         if (!entry_found) {
696                 priv->pattern[group].pattern_type[j] = pattern->type;
697                 priv->pattern[group].item_count++;
698                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
699         }
700
701         /* Get traffic class index and flow id to be configured */
702         flow->tc_id = group;
703         flow->index = attr->priority;
704
705         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
706                 index = priv->extract.qos_key_cfg.num_extracts;
707                 priv->extract.qos_key_cfg.extracts[index].type =
708                                                         DPKG_EXTRACT_FROM_HDR;
709                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
710                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP;
711                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE;
712                 index++;
713
714                 priv->extract.qos_key_cfg.extracts[index].type =
715                                                         DPKG_EXTRACT_FROM_HDR;
716                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
717                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP;
718                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE;
719                 index++;
720
721                 priv->extract.qos_key_cfg.num_extracts = index;
722         }
723
724         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
725                 index = priv->extract.fs_key_cfg[group].num_extracts;
726                 priv->extract.fs_key_cfg[group].extracts[index].type =
727                                                         DPKG_EXTRACT_FROM_HDR;
728                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
729                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP;
730                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE;
731                 index++;
732
733                 priv->extract.fs_key_cfg[group].extracts[index].type =
734                                                         DPKG_EXTRACT_FROM_HDR;
735                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
736                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP;
737                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE;
738                 index++;
739
740                 priv->extract.fs_key_cfg[group].num_extracts = index;
741         }
742
743         /* Parse pattern list to get the matching parameters */
744         spec    = (const struct rte_flow_item_icmp *)pattern->spec;
745         last    = (const struct rte_flow_item_icmp *)pattern->last;
746         mask    = (const struct rte_flow_item_icmp *)
747                         (pattern->mask ? pattern->mask : default_mask);
748
749         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ICMP;
750         memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_type,
751                                                         sizeof(uint8_t));
752         key_iova += sizeof(uint8_t);
753         memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_code,
754                                                         sizeof(uint8_t));
755
756         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ICMP;
757         memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_type,
758                                                         sizeof(uint8_t));
759         key_iova += sizeof(uint8_t);
760         memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_code,
761                                                         sizeof(uint8_t));
762
763         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ICMP +
764                                 (2 * sizeof(uint8_t)));
765
766         return device_configured;
767 }
768
769 static int
770 dpaa2_configure_flow_udp(struct rte_flow *flow,
771                          struct rte_eth_dev *dev,
772                           const struct rte_flow_attr *attr,
773                           const struct rte_flow_item *pattern,
774                           const struct rte_flow_action actions[] __rte_unused,
775                           struct rte_flow_error *error __rte_unused)
776 {
777         int index, j = 0;
778         size_t key_iova;
779         size_t mask_iova;
780         int device_configured = 0, entry_found = 0;
781         uint32_t group;
782         const struct rte_flow_item_udp *spec, *mask;
783
784         const struct rte_flow_item_udp *last __rte_unused;
785         struct dpaa2_dev_priv *priv = dev->data->dev_private;
786
787         group = attr->group;
788
789         /* DPAA2 platform has a limitation that extract parameter can not be */
790         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
791         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
792                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
793                                                 DPKG_MAX_NUM_OF_EXTRACTS);
794                 return -ENOTSUP;
795         }
796
797         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
798                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
799                                                 DPKG_MAX_NUM_OF_EXTRACTS);
800                 return -ENOTSUP;
801         }
802
803         for (j = 0; j < priv->pattern[8].item_count; j++) {
804                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
805                         continue;
806                 } else {
807                          entry_found = 1;
808                         break;
809                 }
810         }
811
812         if (!entry_found) {
813                 priv->pattern[8].pattern_type[j] = pattern->type;
814                 priv->pattern[8].item_count++;
815                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
816         }
817
818         entry_found = 0;
819         for (j = 0; j < priv->pattern[group].item_count; j++) {
820                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
821                         continue;
822                 } else {
823                         entry_found = 1;
824                         break;
825                 }
826         }
827
828         if (!entry_found) {
829                 priv->pattern[group].pattern_type[j] = pattern->type;
830                 priv->pattern[group].item_count++;
831                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
832         }
833
834         /* Get traffic class index and flow id to be configured */
835         flow->tc_id = group;
836         flow->index = attr->priority;
837
838         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
839                 index = priv->extract.qos_key_cfg.num_extracts;
840                 priv->extract.qos_key_cfg.extracts[index].type =
841                                                         DPKG_EXTRACT_FROM_HDR;
842                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
843                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
844                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
845                 index++;
846
847                 priv->extract.qos_key_cfg.extracts[index].type =
848                                                         DPKG_EXTRACT_FROM_HDR;
849                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
850                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP;
851                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC;
852                 index++;
853
854                 priv->extract.qos_key_cfg.extracts[index].type = DPKG_EXTRACT_FROM_HDR;
855                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
856                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP;
857                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST;
858                 index++;
859
860                 priv->extract.qos_key_cfg.num_extracts = index;
861         }
862
863         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
864                 index = priv->extract.fs_key_cfg[group].num_extracts;
865                 priv->extract.fs_key_cfg[group].extracts[index].type =
866                                                         DPKG_EXTRACT_FROM_HDR;
867                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
868                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
869                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
870                 index++;
871
872                 priv->extract.fs_key_cfg[group].extracts[index].type =
873                                                         DPKG_EXTRACT_FROM_HDR;
874                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
875                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP;
876                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC;
877                 index++;
878
879                 priv->extract.fs_key_cfg[group].extracts[index].type =
880                                                         DPKG_EXTRACT_FROM_HDR;
881                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
882                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP;
883                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST;
884                 index++;
885
886                 priv->extract.fs_key_cfg[group].num_extracts = index;
887         }
888
889         /* Parse pattern list to get the matching parameters */
890         spec    = (const struct rte_flow_item_udp *)pattern->spec;
891         last    = (const struct rte_flow_item_udp *)pattern->last;
892         mask    = (const struct rte_flow_item_udp *)
893                         (pattern->mask ? pattern->mask : default_mask);
894
895         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 +
896                                         (2 * sizeof(uint32_t));
897         memset((void *)key_iova, 0x11, sizeof(uint8_t));
898         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_UDP;
899         memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port),
900                                                         sizeof(uint16_t));
901         key_iova +=  sizeof(uint16_t);
902         memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port),
903                                                         sizeof(uint16_t));
904
905         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_UDP;
906         memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port),
907                                                         sizeof(uint16_t));
908         mask_iova +=  sizeof(uint16_t);
909         memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port),
910                                                         sizeof(uint16_t));
911
912         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_UDP +
913                                 (2 * sizeof(uint16_t)));
914
915         return device_configured;
916 }
917
918 static int
919 dpaa2_configure_flow_tcp(struct rte_flow *flow,
920                          struct rte_eth_dev *dev,
921                          const struct rte_flow_attr *attr,
922                          const struct rte_flow_item *pattern,
923                          const struct rte_flow_action actions[] __rte_unused,
924                          struct rte_flow_error *error __rte_unused)
925 {
926         int index, j = 0;
927         size_t key_iova;
928         size_t mask_iova;
929         int device_configured = 0, entry_found = 0;
930         uint32_t group;
931         const struct rte_flow_item_tcp *spec, *mask;
932
933         const struct rte_flow_item_tcp *last __rte_unused;
934         struct dpaa2_dev_priv *priv = dev->data->dev_private;
935
936         group = attr->group;
937
938         /* DPAA2 platform has a limitation that extract parameter can not be */
939         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/
940         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
941                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
942                                                 DPKG_MAX_NUM_OF_EXTRACTS);
943                 return -ENOTSUP;
944         }
945
946         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
947                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
948                                                 DPKG_MAX_NUM_OF_EXTRACTS);
949                 return -ENOTSUP;
950         }
951
952         for (j = 0; j < priv->pattern[8].item_count; j++) {
953                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
954                         continue;
955                 } else {
956                         entry_found = 1;
957                         break;
958                 }
959         }
960
961         if (!entry_found) {
962                 priv->pattern[8].pattern_type[j] = pattern->type;
963                 priv->pattern[8].item_count++;
964                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
965         }
966
967         entry_found = 0;
968         for (j = 0; j < priv->pattern[group].item_count; j++) {
969                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
970                         continue;
971                 } else {
972                         entry_found = 1;
973                         break;
974                 }
975         }
976
977         if (!entry_found) {
978                 priv->pattern[group].pattern_type[j] = pattern->type;
979                 priv->pattern[group].item_count++;
980                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
981         }
982
983         /* Get traffic class index and flow id to be configured */
984         flow->tc_id = group;
985         flow->index = attr->priority;
986
987         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
988                 index = priv->extract.qos_key_cfg.num_extracts;
989                 priv->extract.qos_key_cfg.extracts[index].type =
990                                                         DPKG_EXTRACT_FROM_HDR;
991                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
992                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
993                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
994                 index++;
995
996                 priv->extract.qos_key_cfg.extracts[index].type =
997                                                         DPKG_EXTRACT_FROM_HDR;
998                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
999                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP;
1000                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC;
1001                 index++;
1002
1003                 priv->extract.qos_key_cfg.extracts[index].type =
1004                                                         DPKG_EXTRACT_FROM_HDR;
1005                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1006                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP;
1007                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST;
1008                 index++;
1009
1010                 priv->extract.qos_key_cfg.num_extracts = index;
1011         }
1012
1013         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
1014                 index = priv->extract.fs_key_cfg[group].num_extracts;
1015                 priv->extract.fs_key_cfg[group].extracts[index].type =
1016                                                         DPKG_EXTRACT_FROM_HDR;
1017                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1018                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
1019                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
1020                 index++;
1021
1022                 priv->extract.fs_key_cfg[group].extracts[index].type =
1023                                                         DPKG_EXTRACT_FROM_HDR;
1024                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1025                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP;
1026                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC;
1027                 index++;
1028
1029                 priv->extract.fs_key_cfg[group].extracts[index].type =
1030                                                         DPKG_EXTRACT_FROM_HDR;
1031                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1032                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP;
1033                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST;
1034                 index++;
1035
1036                 priv->extract.fs_key_cfg[group].num_extracts = index;
1037         }
1038
1039         /* Parse pattern list to get the matching parameters */
1040         spec    = (const struct rte_flow_item_tcp *)pattern->spec;
1041         last    = (const struct rte_flow_item_tcp *)pattern->last;
1042         mask    = (const struct rte_flow_item_tcp *)
1043                         (pattern->mask ? pattern->mask : default_mask);
1044
1045         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 +
1046                                         (2 * sizeof(uint32_t));
1047         memset((void *)key_iova, 0x06, sizeof(uint8_t));
1048         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_TCP;
1049         memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port),
1050                                                         sizeof(uint16_t));
1051         key_iova += sizeof(uint16_t);
1052         memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port),
1053                                                         sizeof(uint16_t));
1054
1055         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_TCP;
1056         memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port),
1057                                                         sizeof(uint16_t));
1058         mask_iova += sizeof(uint16_t);
1059         memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port),
1060                                                         sizeof(uint16_t));
1061
1062         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_TCP +
1063                                 (2 * sizeof(uint16_t)));
1064
1065         return device_configured;
1066 }
1067
1068 static int
1069 dpaa2_configure_flow_sctp(struct rte_flow *flow,
1070                           struct rte_eth_dev *dev,
1071                           const struct rte_flow_attr *attr,
1072                           const struct rte_flow_item *pattern,
1073                           const struct rte_flow_action actions[] __rte_unused,
1074                           struct rte_flow_error *error __rte_unused)
1075 {
1076         int index, j = 0;
1077         size_t key_iova;
1078         size_t mask_iova;
1079         int device_configured = 0, entry_found = 0;
1080         uint32_t group;
1081         const struct rte_flow_item_sctp *spec, *mask;
1082
1083         const struct rte_flow_item_sctp *last __rte_unused;
1084         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1085
1086         group = attr->group;
1087
1088         /* DPAA2 platform has a limitation that extract parameter can not be */
1089         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */
1090         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
1091                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
1092                                                 DPKG_MAX_NUM_OF_EXTRACTS);
1093                 return -ENOTSUP;
1094         }
1095
1096         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
1097                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
1098                                                 DPKG_MAX_NUM_OF_EXTRACTS);
1099                 return -ENOTSUP;
1100         }
1101
1102         for (j = 0; j < priv->pattern[8].item_count; j++) {
1103                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
1104                         continue;
1105                 } else {
1106                         entry_found = 1;
1107                         break;
1108                 }
1109         }
1110
1111         if (!entry_found) {
1112                 priv->pattern[8].pattern_type[j] = pattern->type;
1113                 priv->pattern[8].item_count++;
1114                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
1115         }
1116
1117         entry_found = 0;
1118         for (j = 0; j < priv->pattern[group].item_count; j++) {
1119                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
1120                         continue;
1121                 } else {
1122                         entry_found = 1;
1123                         break;
1124                 }
1125         }
1126
1127         if (!entry_found) {
1128                 priv->pattern[group].pattern_type[j] = pattern->type;
1129                 priv->pattern[group].item_count++;
1130                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
1131         }
1132
1133         /* Get traffic class index and flow id to be configured */
1134         flow->tc_id = group;
1135         flow->index = attr->priority;
1136
1137         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
1138                 index = priv->extract.qos_key_cfg.num_extracts;
1139                 priv->extract.qos_key_cfg.extracts[index].type =
1140                                                         DPKG_EXTRACT_FROM_HDR;
1141                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1142                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP;
1143                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
1144                 index++;
1145
1146                 priv->extract.qos_key_cfg.extracts[index].type =
1147                                                         DPKG_EXTRACT_FROM_HDR;
1148                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1149                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP;
1150                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC;
1151                 index++;
1152
1153                 priv->extract.qos_key_cfg.extracts[index].type =
1154                                                         DPKG_EXTRACT_FROM_HDR;
1155                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1156                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP;
1157                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST;
1158                 index++;
1159
1160                 priv->extract.qos_key_cfg.num_extracts = index;
1161         }
1162
1163         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
1164                 index = priv->extract.fs_key_cfg[group].num_extracts;
1165                 priv->extract.fs_key_cfg[group].extracts[index].type =
1166                                                         DPKG_EXTRACT_FROM_HDR;
1167                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1168                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP;
1169                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO;
1170                 index++;
1171
1172                 priv->extract.fs_key_cfg[group].extracts[index].type =
1173                                                         DPKG_EXTRACT_FROM_HDR;
1174                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1175                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP;
1176                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC;
1177                 index++;
1178
1179                 priv->extract.fs_key_cfg[group].extracts[index].type =
1180                                                         DPKG_EXTRACT_FROM_HDR;
1181                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1182                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP;
1183                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST;
1184                 index++;
1185
1186                 priv->extract.fs_key_cfg[group].num_extracts = index;
1187         }
1188
1189         /* Parse pattern list to get the matching parameters */
1190         spec    = (const struct rte_flow_item_sctp *)pattern->spec;
1191         last    = (const struct rte_flow_item_sctp *)pattern->last;
1192         mask    = (const struct rte_flow_item_sctp *)
1193                         (pattern->mask ? pattern->mask : default_mask);
1194
1195         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 +
1196                                                 (2 * sizeof(uint32_t));
1197         memset((void *)key_iova, 0x84, sizeof(uint8_t));
1198         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_SCTP;
1199         memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port),
1200                                                         sizeof(uint16_t));
1201         key_iova += sizeof(uint16_t);
1202         memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port),
1203                                                         sizeof(uint16_t));
1204
1205         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_SCTP;
1206         memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port),
1207                                                         sizeof(uint16_t));
1208         mask_iova += sizeof(uint16_t);
1209         memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port),
1210                                                         sizeof(uint16_t));
1211
1212         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_SCTP +
1213                                 (2 * sizeof(uint16_t)));
1214         return device_configured;
1215 }
1216
1217 static int
1218 dpaa2_configure_flow_gre(struct rte_flow *flow,
1219                          struct rte_eth_dev *dev,
1220                          const struct rte_flow_attr *attr,
1221                          const struct rte_flow_item *pattern,
1222                          const struct rte_flow_action actions[] __rte_unused,
1223                          struct rte_flow_error *error __rte_unused)
1224 {
1225         int index, j = 0;
1226         size_t key_iova;
1227         size_t mask_iova;
1228         int device_configured = 0, entry_found = 0;
1229         uint32_t group;
1230         const struct rte_flow_item_gre *spec, *mask;
1231
1232         const struct rte_flow_item_gre *last __rte_unused;
1233         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1234
1235         group = attr->group;
1236
1237         /* DPAA2 platform has a limitation that extract parameter can not be */
1238         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */
1239         if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
1240                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
1241                                                 DPKG_MAX_NUM_OF_EXTRACTS);
1242                 return -ENOTSUP;
1243         }
1244
1245         if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) {
1246                 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n",
1247                                                 DPKG_MAX_NUM_OF_EXTRACTS);
1248                 return -ENOTSUP;
1249         }
1250
1251         for (j = 0; j < priv->pattern[8].item_count; j++) {
1252                 if (priv->pattern[8].pattern_type[j] != pattern->type) {
1253                         continue;
1254                 } else {
1255                         entry_found = 1;
1256                         break;
1257                 }
1258         }
1259
1260         if (!entry_found) {
1261                 priv->pattern[8].pattern_type[j] = pattern->type;
1262                 priv->pattern[8].item_count++;
1263                 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE;
1264         }
1265
1266         entry_found = 0;
1267         for (j = 0; j < priv->pattern[group].item_count; j++) {
1268                 if (priv->pattern[group].pattern_type[j] != pattern->type) {
1269                         continue;
1270                 } else {
1271                         entry_found = 1;
1272                         break;
1273                 }
1274         }
1275
1276         if (!entry_found) {
1277                 priv->pattern[group].pattern_type[j] = pattern->type;
1278                 priv->pattern[group].item_count++;
1279                 device_configured |= DPAA2_FS_TABLE_RECONFIGURE;
1280         }
1281
1282         /* Get traffic class index and flow id to be configured */
1283         flow->tc_id = group;
1284         flow->index = attr->priority;
1285
1286         if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
1287                 index = priv->extract.qos_key_cfg.num_extracts;
1288                 priv->extract.qos_key_cfg.extracts[index].type =
1289                                                         DPKG_EXTRACT_FROM_HDR;
1290                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1291                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_GRE;
1292                 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE;
1293                 index++;
1294
1295                 priv->extract.qos_key_cfg.num_extracts = index;
1296         }
1297
1298         if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) {
1299                 index = priv->extract.fs_key_cfg[group].num_extracts;
1300                 priv->extract.fs_key_cfg[group].extracts[index].type =
1301                                                         DPKG_EXTRACT_FROM_HDR;
1302                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
1303                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_GRE;
1304                 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE;
1305                 index++;
1306
1307                 priv->extract.fs_key_cfg[group].num_extracts = index;
1308         }
1309
1310         /* Parse pattern list to get the matching parameters */
1311         spec    = (const struct rte_flow_item_gre *)pattern->spec;
1312         last    = (const struct rte_flow_item_gre *)pattern->last;
1313         mask    = (const struct rte_flow_item_gre *)
1314                         (pattern->mask ? pattern->mask : default_mask);
1315
1316         key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_GRE;
1317         memcpy((void *)key_iova, (const void *)(&spec->protocol),
1318                                                         sizeof(rte_be16_t));
1319
1320         mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_GRE;
1321         memcpy((void *)mask_iova, (const void *)(&mask->protocol),
1322                                                         sizeof(rte_be16_t));
1323
1324         flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_GRE + sizeof(rte_be16_t));
1325
1326         return device_configured;
1327 }
1328
1329 static int
1330 dpaa2_generic_flow_set(struct rte_flow *flow,
1331                        struct rte_eth_dev *dev,
1332                        const struct rte_flow_attr *attr,
1333                        const struct rte_flow_item pattern[],
1334                        const struct rte_flow_action actions[],
1335                        struct rte_flow_error *error)
1336 {
1337         const struct rte_flow_action_queue *dest_queue;
1338         const struct rte_flow_action_rss *rss_conf;
1339         uint16_t index;
1340         int is_keycfg_configured = 0, end_of_list = 0;
1341         int ret = 0, i = 0, j = 0;
1342         struct dpni_attr nic_attr;
1343         struct dpni_rx_tc_dist_cfg tc_cfg;
1344         struct dpni_qos_tbl_cfg qos_cfg;
1345         struct dpkg_profile_cfg key_cfg;
1346         struct dpni_fs_action_cfg action;
1347         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1348         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1349         size_t param;
1350
1351         /* Parse pattern list to get the matching parameters */
1352         while (!end_of_list) {
1353                 switch (pattern[i].type) {
1354                 case RTE_FLOW_ITEM_TYPE_ETH:
1355                         is_keycfg_configured = dpaa2_configure_flow_eth(flow,
1356                                                                         dev,
1357                                                                         attr,
1358                                                                         &pattern[i],
1359                                                                         actions,
1360                                                                         error);
1361                         break;
1362                 case RTE_FLOW_ITEM_TYPE_VLAN:
1363                         is_keycfg_configured = dpaa2_configure_flow_vlan(flow,
1364                                                                         dev,
1365                                                                         attr,
1366                                                                         &pattern[i],
1367                                                                         actions,
1368                                                                         error);
1369                         break;
1370                 case RTE_FLOW_ITEM_TYPE_IPV4:
1371                         is_keycfg_configured = dpaa2_configure_flow_ipv4(flow,
1372                                                                         dev,
1373                                                                         attr,
1374                                                                         &pattern[i],
1375                                                                         actions,
1376                                                                         error);
1377                         break;
1378                 case RTE_FLOW_ITEM_TYPE_IPV6:
1379                         is_keycfg_configured = dpaa2_configure_flow_ipv6(flow,
1380                                                                         dev,
1381                                                                         attr,
1382                                                                         &pattern[i],
1383                                                                         actions,
1384                                                                         error);
1385                         break;
1386                 case RTE_FLOW_ITEM_TYPE_ICMP:
1387                         is_keycfg_configured = dpaa2_configure_flow_icmp(flow,
1388                                                                         dev,
1389                                                                         attr,
1390                                                                         &pattern[i],
1391                                                                         actions,
1392                                                                         error);
1393                         break;
1394                 case RTE_FLOW_ITEM_TYPE_UDP:
1395                         is_keycfg_configured = dpaa2_configure_flow_udp(flow,
1396                                                                         dev,
1397                                                                         attr,
1398                                                                         &pattern[i],
1399                                                                         actions,
1400                                                                         error);
1401                         break;
1402                 case RTE_FLOW_ITEM_TYPE_TCP:
1403                         is_keycfg_configured = dpaa2_configure_flow_tcp(flow,
1404                                                                         dev,
1405                                                                         attr,
1406                                                                         &pattern[i],
1407                                                                         actions,
1408                                                                         error);
1409                         break;
1410                 case RTE_FLOW_ITEM_TYPE_SCTP:
1411                         is_keycfg_configured = dpaa2_configure_flow_sctp(flow,
1412                                                                         dev, attr,
1413                                                                         &pattern[i],
1414                                                                         actions,
1415                                                                         error);
1416                         break;
1417                 case RTE_FLOW_ITEM_TYPE_GRE:
1418                         is_keycfg_configured = dpaa2_configure_flow_gre(flow,
1419                                                                         dev,
1420                                                                         attr,
1421                                                                         &pattern[i],
1422                                                                         actions,
1423                                                                         error);
1424                         break;
1425                 case RTE_FLOW_ITEM_TYPE_END:
1426                         end_of_list = 1;
1427                         break; /*End of List*/
1428                 default:
1429                         DPAA2_PMD_ERR("Invalid action type");
1430                         ret = -ENOTSUP;
1431                         break;
1432                 }
1433                 i++;
1434         }
1435
1436         /* Let's parse action on matching traffic */
1437         end_of_list = 0;
1438         while (!end_of_list) {
1439                 switch (actions[j].type) {
1440                 case RTE_FLOW_ACTION_TYPE_QUEUE:
1441                         dest_queue = (const struct rte_flow_action_queue *)(actions[j].conf);
1442                         flow->flow_id = dest_queue->index;
1443                         flow->action = RTE_FLOW_ACTION_TYPE_QUEUE;
1444                         memset(&action, 0, sizeof(struct dpni_fs_action_cfg));
1445                         action.flow_id = flow->flow_id;
1446                         if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
1447                                 if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg,
1448                                                          (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
1449                                         DPAA2_PMD_ERR(
1450                                         "Unable to prepare extract parameters");
1451                                         return -1;
1452                                 }
1453
1454                                 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
1455                                 qos_cfg.discard_on_miss = true;
1456                                 qos_cfg.keep_entries = true;
1457                                 qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param;
1458                                 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
1459                                                          priv->token, &qos_cfg);
1460                                 if (ret < 0) {
1461                                         DPAA2_PMD_ERR(
1462                                         "Distribution cannot be configured.(%d)"
1463                                         , ret);
1464                                         return -1;
1465                                 }
1466                         }
1467                         if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
1468                                 if (dpkg_prepare_key_cfg(&priv->extract.fs_key_cfg[flow->tc_id],
1469                                                 (uint8_t *)(size_t)priv->extract.fs_extract_param[flow->tc_id]) < 0) {
1470                                         DPAA2_PMD_ERR(
1471                                         "Unable to prepare extract parameters");
1472                                         return -1;
1473                                 }
1474
1475                                 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
1476                                 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc;
1477                                 tc_cfg.dist_mode = DPNI_DIST_MODE_FS;
1478                                 tc_cfg.key_cfg_iova =
1479                                         (uint64_t)priv->extract.fs_extract_param[flow->tc_id];
1480                                 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
1481                                 tc_cfg.fs_cfg.keep_entries = true;
1482                                 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
1483                                                          priv->token,
1484                                                          flow->tc_id, &tc_cfg);
1485                                 if (ret < 0) {
1486                                         DPAA2_PMD_ERR(
1487                                         "Distribution cannot be configured.(%d)"
1488                                         , ret);
1489                                         return -1;
1490                                 }
1491                         }
1492                         /* Configure QoS table first */
1493                         memset(&nic_attr, 0, sizeof(struct dpni_attr));
1494                         ret = dpni_get_attributes(dpni, CMD_PRI_LOW,
1495                                                  priv->token, &nic_attr);
1496                         if (ret < 0) {
1497                                 DPAA2_PMD_ERR(
1498                                 "Failure to get attribute. dpni@%p err code(%d)\n",
1499                                 dpni, ret);
1500                                 return ret;
1501                         }
1502
1503                         action.flow_id = action.flow_id % nic_attr.num_rx_tcs;
1504                         index = flow->index + (flow->tc_id * nic_attr.fs_entries);
1505                         ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
1506                                                 priv->token, &flow->rule,
1507                                                 flow->tc_id, index);
1508                         if (ret < 0) {
1509                                 DPAA2_PMD_ERR(
1510                                 "Error in addnig entry to QoS table(%d)", ret);
1511                                 return ret;
1512                         }
1513
1514                         /* Then Configure FS table */
1515                         ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token,
1516                                                 flow->tc_id, flow->index,
1517                                                 &flow->rule, &action);
1518                         if (ret < 0) {
1519                                 DPAA2_PMD_ERR(
1520                                 "Error in adding entry to FS table(%d)", ret);
1521                                 return ret;
1522                         }
1523                         break;
1524                 case RTE_FLOW_ACTION_TYPE_RSS:
1525                         ret = dpni_get_attributes(dpni, CMD_PRI_LOW,
1526                                                  priv->token, &nic_attr);
1527                         if (ret < 0) {
1528                                 DPAA2_PMD_ERR(
1529                                 "Failure to get attribute. dpni@%p err code(%d)\n",
1530                                 dpni, ret);
1531                                 return ret;
1532                         }
1533                         rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf);
1534                         for (i = 0; i < (int)rss_conf->queue_num; i++) {
1535                                 if (rss_conf->queue[i] < (attr->group * nic_attr.num_queues) ||
1536                                     rss_conf->queue[i] >= ((attr->group + 1) * nic_attr.num_queues)) {
1537                                         DPAA2_PMD_ERR(
1538                                         "Queue/Group combination are not supported\n");
1539                                         return -ENOTSUP;
1540                                 }
1541                         }
1542
1543                         flow->action = RTE_FLOW_ACTION_TYPE_RSS;
1544                         ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
1545                                                                 &key_cfg);
1546                         if (ret < 0) {
1547                                 DPAA2_PMD_ERR(
1548                                 "unable to set flow distribution.please check queue config\n");
1549                                 return ret;
1550                         }
1551
1552                         /* Allocate DMA'ble memory to write the rules */
1553                         param = (size_t)rte_malloc(NULL, 256, 64);
1554                         if (!param) {
1555                                 DPAA2_PMD_ERR("Memory allocation failure\n");
1556                                 return -1;
1557                         }
1558
1559                         if (dpkg_prepare_key_cfg(&key_cfg, (uint8_t *)param) < 0) {
1560                                 DPAA2_PMD_ERR(
1561                                 "Unable to prepare extract parameters");
1562                                 rte_free((void *)param);
1563                                 return -1;
1564                         }
1565
1566                         memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
1567                         tc_cfg.dist_size = rss_conf->queue_num;
1568                         tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
1569                         tc_cfg.key_cfg_iova = (size_t)param;
1570                         tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
1571
1572                         ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
1573                                                  priv->token, flow->tc_id,
1574                                                  &tc_cfg);
1575                         if (ret < 0) {
1576                                 DPAA2_PMD_ERR(
1577                                 "Distribution cannot be configured: %d\n", ret);
1578                                 rte_free((void *)param);
1579                                 return -1;
1580                         }
1581
1582                         rte_free((void *)param);
1583                         if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
1584                                 if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg,
1585                                         (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
1586                                         DPAA2_PMD_ERR(
1587                                         "Unable to prepare extract parameters");
1588                                         return -1;
1589                                 }
1590                                 memset(&qos_cfg, 0,
1591                                         sizeof(struct dpni_qos_tbl_cfg));
1592                                 qos_cfg.discard_on_miss = true;
1593                                 qos_cfg.keep_entries = true;
1594                                 qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param;
1595                                 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
1596                                                          priv->token, &qos_cfg);
1597                                 if (ret < 0) {
1598                                         DPAA2_PMD_ERR(
1599                                         "Distribution can not be configured(%d)\n",
1600                                         ret);
1601                                         return -1;
1602                                 }
1603                         }
1604
1605                         /* Add Rule into QoS table */
1606                         index = flow->index + (flow->tc_id * nic_attr.fs_entries);
1607                         ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token,
1608                                                 &flow->rule, flow->tc_id,
1609                                                 index);
1610                         if (ret < 0) {
1611                                 DPAA2_PMD_ERR(
1612                                 "Error in entry addition in QoS table(%d)",
1613                                 ret);
1614                                 return ret;
1615                         }
1616                         break;
1617                 case RTE_FLOW_ACTION_TYPE_END:
1618                         end_of_list = 1;
1619                         break;
1620                 default:
1621                         DPAA2_PMD_ERR("Invalid action type");
1622                         ret = -ENOTSUP;
1623                         break;
1624                 }
1625                 j++;
1626         }
1627
1628         return ret;
1629 }
1630
1631 static inline int
1632 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
1633                       const struct rte_flow_attr *attr)
1634 {
1635         int ret = 0;
1636
1637         if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
1638                 DPAA2_PMD_ERR("Priority group is out of range\n");
1639                 ret = -ENOTSUP;
1640         }
1641         if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
1642                 DPAA2_PMD_ERR("Priority within the group is out of range\n");
1643                 ret = -ENOTSUP;
1644         }
1645         if (unlikely(attr->egress)) {
1646                 DPAA2_PMD_ERR(
1647                         "Flow configuration is not supported on egress side\n");
1648                 ret = -ENOTSUP;
1649         }
1650         if (unlikely(!attr->ingress)) {
1651                 DPAA2_PMD_ERR("Ingress flag must be configured\n");
1652                 ret = -EINVAL;
1653         }
1654         return ret;
1655 }
1656
1657 static inline void
1658 dpaa2_dev_update_default_mask(const struct rte_flow_item *pattern)
1659 {
1660         switch (pattern->type) {
1661         case RTE_FLOW_ITEM_TYPE_ETH:
1662                 default_mask = (const void *)&rte_flow_item_eth_mask;
1663                 break;
1664         case RTE_FLOW_ITEM_TYPE_VLAN:
1665                 default_mask = (const void *)&rte_flow_item_vlan_mask;
1666                 break;
1667         case RTE_FLOW_ITEM_TYPE_IPV4:
1668                 default_mask = (const void *)&rte_flow_item_ipv4_mask;
1669                 break;
1670         case RTE_FLOW_ITEM_TYPE_IPV6:
1671                 default_mask = (const void *)&rte_flow_item_ipv6_mask;
1672                 break;
1673         case RTE_FLOW_ITEM_TYPE_ICMP:
1674                 default_mask = (const void *)&rte_flow_item_icmp_mask;
1675                 break;
1676         case RTE_FLOW_ITEM_TYPE_UDP:
1677                 default_mask = (const void *)&rte_flow_item_udp_mask;
1678                 break;
1679         case RTE_FLOW_ITEM_TYPE_TCP:
1680                 default_mask = (const void *)&rte_flow_item_tcp_mask;
1681                 break;
1682         case RTE_FLOW_ITEM_TYPE_SCTP:
1683                 default_mask = (const void *)&rte_flow_item_sctp_mask;
1684                 break;
1685         case RTE_FLOW_ITEM_TYPE_GRE:
1686                 default_mask = (const void *)&rte_flow_item_gre_mask;
1687                 break;
1688         default:
1689                 DPAA2_PMD_ERR("Invalid pattern type");
1690         }
1691 }
1692
1693 static inline int
1694 dpaa2_dev_verify_patterns(struct dpaa2_dev_priv *dev_priv,
1695                           const struct rte_flow_item pattern[])
1696 {
1697         unsigned int i, j, k, is_found = 0;
1698         int ret = 0;
1699
1700         for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
1701                 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) {
1702                         if (dpaa2_supported_pattern_type[i] == pattern[j].type) {
1703                                 is_found = 1;
1704                                 break;
1705                         }
1706                 }
1707                 if (!is_found) {
1708                         ret = -ENOTSUP;
1709                         break;
1710                 }
1711         }
1712         /* Lets verify other combinations of given pattern rules */
1713         for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
1714                 if (!pattern[j].spec) {
1715                         ret = -EINVAL;
1716                         break;
1717                 }
1718                 if ((pattern[j].last) && (!pattern[j].mask))
1719                         dpaa2_dev_update_default_mask(&pattern[j]);
1720         }
1721
1722         /* DPAA2 platform has a limitation that extract parameter can not be */
1723         /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */
1724         for (i = 0; pattern[i].type != RTE_FLOW_ITEM_TYPE_END; i++) {
1725                 for (j = 0; j < MAX_TCS + 1; j++) {
1726                                 for (k = 0; k < DPKG_MAX_NUM_OF_EXTRACTS; j++) {
1727                                         if (dev_priv->pattern[j].pattern_type[k] == pattern[i].type)
1728                                                 break;
1729                                 }
1730                         if (dev_priv->pattern[j].item_count >= DPKG_MAX_NUM_OF_EXTRACTS)
1731                                 ret = -ENOTSUP;
1732                 }
1733         }
1734         return ret;
1735 }
1736
1737 static inline int
1738 dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
1739 {
1740         unsigned int i, j, is_found = 0;
1741         int ret = 0;
1742
1743         for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
1744                 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
1745                         if (dpaa2_supported_action_type[i] == actions[j].type) {
1746                                 is_found = 1;
1747                                 break;
1748                         }
1749                 }
1750                 if (!is_found) {
1751                         ret = -ENOTSUP;
1752                         break;
1753                 }
1754         }
1755         for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
1756                 if ((actions[j].type != RTE_FLOW_ACTION_TYPE_DROP) && (!actions[j].conf))
1757                         ret = -EINVAL;
1758         }
1759         return ret;
1760 }
1761
1762 static
1763 int dpaa2_flow_validate(struct rte_eth_dev *dev,
1764                         const struct rte_flow_attr *flow_attr,
1765                         const struct rte_flow_item pattern[],
1766                         const struct rte_flow_action actions[],
1767                         struct rte_flow_error *error __rte_unused)
1768 {
1769         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1770         struct dpni_attr dpni_attr;
1771         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1772         uint16_t token = priv->token;
1773         int ret = 0;
1774
1775         memset(&dpni_attr, 0, sizeof(struct dpni_attr));
1776         ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
1777         if (ret < 0) {
1778                 DPAA2_PMD_ERR(
1779                         "Failure to get dpni@%p attribute, err code  %d\n",
1780                         dpni, ret);
1781                 return ret;
1782         }
1783
1784         /* Verify input attributes */
1785         ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
1786         if (ret < 0) {
1787                 DPAA2_PMD_ERR(
1788                         "Invalid attributes are given\n");
1789                 goto not_valid_params;
1790         }
1791         /* Verify input pattern list */
1792         ret = dpaa2_dev_verify_patterns(priv, pattern);
1793         if (ret < 0) {
1794                 DPAA2_PMD_ERR(
1795                         "Invalid pattern list is given\n");
1796                 goto not_valid_params;
1797         }
1798         /* Verify input action list */
1799         ret = dpaa2_dev_verify_actions(actions);
1800         if (ret < 0) {
1801                 DPAA2_PMD_ERR(
1802                         "Invalid action list is given\n");
1803                 goto not_valid_params;
1804         }
1805 not_valid_params:
1806         return ret;
1807 }
1808
1809 static
1810 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev,
1811                                    const struct rte_flow_attr *attr,
1812                                    const struct rte_flow_item pattern[],
1813                                    const struct rte_flow_action actions[],
1814                                    struct rte_flow_error *error)
1815 {
1816         struct rte_flow *flow = NULL;
1817         size_t key_iova = 0, mask_iova = 0;
1818         int ret;
1819
1820         flow = rte_malloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE);
1821         if (!flow) {
1822                 DPAA2_PMD_ERR("Failure to allocate memory for flow");
1823                 return NULL;
1824         }
1825         /* Allocate DMA'ble memory to write the rules */
1826         key_iova = (size_t)rte_malloc(NULL, 256, 64);
1827         if (!key_iova) {
1828                 DPAA2_PMD_ERR(
1829                         "Memory allocation failure for rule configration\n");
1830                 goto creation_error;
1831         }
1832         mask_iova = (size_t)rte_malloc(NULL, 256, 64);
1833         if (!mask_iova) {
1834                 DPAA2_PMD_ERR(
1835                         "Memory allocation failure for rule configration\n");
1836                 goto creation_error;
1837         }
1838
1839         flow->rule.key_iova = key_iova;
1840         flow->rule.mask_iova = mask_iova;
1841         flow->rule.key_size = 0;
1842
1843         switch (dpaa2_filter_type) {
1844         case RTE_ETH_FILTER_GENERIC:
1845                 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern,
1846                                              actions, error);
1847                 if (ret < 0) {
1848                         DPAA2_PMD_ERR(
1849                         "Failure to create flow, return code (%d)", ret);
1850                         goto creation_error;
1851                 }
1852                 break;
1853         default:
1854                 DPAA2_PMD_ERR("Filter type (%d) not supported",
1855                 dpaa2_filter_type);
1856                 break;
1857         }
1858
1859         return flow;
1860
1861 creation_error:
1862         if (flow)
1863                 rte_free((void *)flow);
1864         if (key_iova)
1865                 rte_free((void *)key_iova);
1866         if (mask_iova)
1867                 rte_free((void *)mask_iova);
1868         return NULL;
1869 }
1870
1871 static
1872 int dpaa2_flow_destroy(struct rte_eth_dev *dev,
1873                        struct rte_flow *flow,
1874                        struct rte_flow_error *error __rte_unused)
1875 {
1876         int ret = 0;
1877         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1878         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1879
1880         switch (flow->action) {
1881         case RTE_FLOW_ACTION_TYPE_QUEUE:
1882                 /* Remove entry from QoS table first */
1883                 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
1884                                            &flow->rule);
1885                 if (ret < 0) {
1886                         DPAA2_PMD_ERR(
1887                                 "Error in adding entry to QoS table(%d)", ret);
1888                         goto error;
1889                 }
1890
1891                 /* Then remove entry from FS table */
1892                 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
1893                                            flow->tc_id, &flow->rule);
1894                 if (ret < 0) {
1895                         DPAA2_PMD_ERR(
1896                                 "Error in entry addition in FS table(%d)", ret);
1897                         goto error;
1898                 }
1899                 break;
1900         case RTE_FLOW_ACTION_TYPE_RSS:
1901                 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
1902                                            &flow->rule);
1903                 if (ret < 0) {
1904                         DPAA2_PMD_ERR(
1905                         "Error in entry addition in QoS table(%d)", ret);
1906                         goto error;
1907                 }
1908                 break;
1909         default:
1910                 DPAA2_PMD_ERR(
1911                 "Action type (%d) is not supported", flow->action);
1912                 ret = -ENOTSUP;
1913                 break;
1914         }
1915
1916         /* Now free the flow */
1917         rte_free(flow);
1918
1919 error:
1920         return ret;
1921 }
1922
1923 static int
1924 dpaa2_flow_flush(struct rte_eth_dev *dev,
1925                  struct rte_flow_error *error __rte_unused)
1926 {
1927         int ret = 0, tc_id;
1928         struct dpni_rx_tc_dist_cfg tc_cfg;
1929         struct dpni_qos_tbl_cfg qos_cfg;
1930         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1931         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1932
1933         /* Reset QoS table */
1934         qos_cfg.default_tc = 0;
1935         qos_cfg.discard_on_miss = false;
1936         qos_cfg.keep_entries = false;
1937         qos_cfg.key_cfg_iova = priv->extract.qos_extract_param;
1938         ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, priv->token, &qos_cfg);
1939         if (ret < 0)
1940                 DPAA2_PMD_ERR(
1941                         "QoS table is not reset to default: %d\n", ret);
1942
1943         for (tc_id = 0; tc_id < priv->num_rx_tc; tc_id++) {
1944                 /* Reset FS table */
1945                 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
1946                 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token,
1947                                          tc_id, &tc_cfg);
1948                 if (ret < 0)
1949                         DPAA2_PMD_ERR(
1950                         "Error (%d) in flushing entries for TC (%d)",
1951                         ret, tc_id);
1952         }
1953         return ret;
1954 }
1955
1956 static int
1957 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
1958                 struct rte_flow *flow __rte_unused,
1959                 const struct rte_flow_action *actions __rte_unused,
1960                 void *data __rte_unused,
1961                 struct rte_flow_error *error __rte_unused)
1962 {
1963         return 0;
1964 }
1965
1966 const struct rte_flow_ops dpaa2_flow_ops = {
1967         .create = dpaa2_flow_create,
1968         .validate = dpaa2_flow_validate,
1969         .destroy = dpaa2_flow_destroy,
1970         .flush  = dpaa2_flow_flush,
1971         .query  = dpaa2_flow_query,
1972 };