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