1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2018-2020 NXP
13 #include <rte_ethdev.h>
15 #include <rte_malloc.h>
16 #include <rte_flow_driver.h>
17 #include <rte_tailq.h>
22 #include <dpaa2_ethdev.h>
23 #include <dpaa2_pmd_logs.h>
25 /* Workaround to discriminate the UDP/TCP/SCTP
26 * with next protocol of l3.
27 * MC/WRIOP are not able to identify
28 * the l4 protocol with l4 ports.
30 int mc_l4_port_identification;
32 static char *dpaa2_flow_control_log;
34 #define FIXED_ENTRY_SIZE 54
36 enum flow_rule_ipaddr_type {
42 struct flow_rule_ipaddr {
43 enum flow_rule_ipaddr_type ipaddr_type;
51 LIST_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
52 struct dpni_rule_cfg qos_rule;
53 struct dpni_rule_cfg fs_rule;
54 uint8_t qos_real_key_size;
55 uint8_t fs_real_key_size;
56 uint8_t tc_id; /** Traffic Class ID. */
57 uint8_t tc_index; /** index within this Traffic Class. */
58 enum rte_flow_action_type action;
60 /* Special for IP address to specify the offset
63 struct flow_rule_ipaddr ipaddr_rule;
64 struct dpni_fs_action_cfg action_cfg;
68 enum rte_flow_item_type dpaa2_supported_pattern_type[] = {
69 RTE_FLOW_ITEM_TYPE_END,
70 RTE_FLOW_ITEM_TYPE_ETH,
71 RTE_FLOW_ITEM_TYPE_VLAN,
72 RTE_FLOW_ITEM_TYPE_IPV4,
73 RTE_FLOW_ITEM_TYPE_IPV6,
74 RTE_FLOW_ITEM_TYPE_ICMP,
75 RTE_FLOW_ITEM_TYPE_UDP,
76 RTE_FLOW_ITEM_TYPE_TCP,
77 RTE_FLOW_ITEM_TYPE_SCTP,
78 RTE_FLOW_ITEM_TYPE_GRE,
82 enum rte_flow_action_type dpaa2_supported_action_type[] = {
83 RTE_FLOW_ACTION_TYPE_END,
84 RTE_FLOW_ACTION_TYPE_QUEUE,
85 RTE_FLOW_ACTION_TYPE_RSS
88 /* Max of enum rte_flow_item_type + 1, for both IPv4 and IPv6*/
89 #define DPAA2_FLOW_ITEM_TYPE_GENERIC_IP (RTE_FLOW_ITEM_TYPE_META + 1)
91 enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE;
94 static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = {
95 .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
96 .src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
97 .type = RTE_BE16(0xffff),
100 static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = {
101 .tci = RTE_BE16(0xffff),
104 static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = {
105 .hdr.src_addr = RTE_BE32(0xffffffff),
106 .hdr.dst_addr = RTE_BE32(0xffffffff),
107 .hdr.next_proto_id = 0xff,
110 static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = {
113 "\xff\xff\xff\xff\xff\xff\xff\xff"
114 "\xff\xff\xff\xff\xff\xff\xff\xff",
116 "\xff\xff\xff\xff\xff\xff\xff\xff"
117 "\xff\xff\xff\xff\xff\xff\xff\xff",
122 static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = {
123 .hdr.icmp_type = 0xff,
124 .hdr.icmp_code = 0xff,
127 static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = {
129 .src_port = RTE_BE16(0xffff),
130 .dst_port = RTE_BE16(0xffff),
134 static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = {
136 .src_port = RTE_BE16(0xffff),
137 .dst_port = RTE_BE16(0xffff),
141 static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = {
143 .src_port = RTE_BE16(0xffff),
144 .dst_port = RTE_BE16(0xffff),
148 static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = {
149 .protocol = RTE_BE16(0xffff),
154 static inline void dpaa2_prot_field_string(
155 enum net_prot prot, uint32_t field,
158 if (!dpaa2_flow_control_log)
161 if (prot == NET_PROT_ETH) {
162 strcpy(string, "eth");
163 if (field == NH_FLD_ETH_DA)
164 strcat(string, ".dst");
165 else if (field == NH_FLD_ETH_SA)
166 strcat(string, ".src");
167 else if (field == NH_FLD_ETH_TYPE)
168 strcat(string, ".type");
170 strcat(string, ".unknown field");
171 } else if (prot == NET_PROT_VLAN) {
172 strcpy(string, "vlan");
173 if (field == NH_FLD_VLAN_TCI)
174 strcat(string, ".tci");
176 strcat(string, ".unknown field");
177 } else if (prot == NET_PROT_IP) {
178 strcpy(string, "ip");
179 if (field == NH_FLD_IP_SRC)
180 strcat(string, ".src");
181 else if (field == NH_FLD_IP_DST)
182 strcat(string, ".dst");
183 else if (field == NH_FLD_IP_PROTO)
184 strcat(string, ".proto");
186 strcat(string, ".unknown field");
187 } else if (prot == NET_PROT_TCP) {
188 strcpy(string, "tcp");
189 if (field == NH_FLD_TCP_PORT_SRC)
190 strcat(string, ".src");
191 else if (field == NH_FLD_TCP_PORT_DST)
192 strcat(string, ".dst");
194 strcat(string, ".unknown field");
195 } else if (prot == NET_PROT_UDP) {
196 strcpy(string, "udp");
197 if (field == NH_FLD_UDP_PORT_SRC)
198 strcat(string, ".src");
199 else if (field == NH_FLD_UDP_PORT_DST)
200 strcat(string, ".dst");
202 strcat(string, ".unknown field");
203 } else if (prot == NET_PROT_ICMP) {
204 strcpy(string, "icmp");
205 if (field == NH_FLD_ICMP_TYPE)
206 strcat(string, ".type");
207 else if (field == NH_FLD_ICMP_CODE)
208 strcat(string, ".code");
210 strcat(string, ".unknown field");
211 } else if (prot == NET_PROT_SCTP) {
212 strcpy(string, "sctp");
213 if (field == NH_FLD_SCTP_PORT_SRC)
214 strcat(string, ".src");
215 else if (field == NH_FLD_SCTP_PORT_DST)
216 strcat(string, ".dst");
218 strcat(string, ".unknown field");
219 } else if (prot == NET_PROT_GRE) {
220 strcpy(string, "gre");
221 if (field == NH_FLD_GRE_TYPE)
222 strcat(string, ".type");
224 strcat(string, ".unknown field");
226 strcpy(string, "unknown protocol");
230 static inline void dpaa2_flow_qos_table_extracts_log(
231 const struct dpaa2_dev_priv *priv)
236 if (!dpaa2_flow_control_log)
239 printf("Setup QoS table: number of extracts: %d\r\n",
240 priv->extract.qos_key_extract.dpkg.num_extracts);
241 for (idx = 0; idx < priv->extract.qos_key_extract.dpkg.num_extracts;
243 dpaa2_prot_field_string(priv->extract.qos_key_extract.dpkg
244 .extracts[idx].extract.from_hdr.prot,
245 priv->extract.qos_key_extract.dpkg.extracts[idx]
246 .extract.from_hdr.field,
248 printf("%s", string);
249 if ((idx + 1) < priv->extract.qos_key_extract.dpkg.num_extracts)
255 static inline void dpaa2_flow_fs_table_extracts_log(
256 const struct dpaa2_dev_priv *priv, int tc_id)
261 if (!dpaa2_flow_control_log)
264 printf("Setup FS table: number of extracts of TC[%d]: %d\r\n",
265 tc_id, priv->extract.tc_key_extract[tc_id]
267 for (idx = 0; idx < priv->extract.tc_key_extract[tc_id]
268 .dpkg.num_extracts; idx++) {
269 dpaa2_prot_field_string(priv->extract.tc_key_extract[tc_id]
270 .dpkg.extracts[idx].extract.from_hdr.prot,
271 priv->extract.tc_key_extract[tc_id].dpkg.extracts[idx]
272 .extract.from_hdr.field,
274 printf("%s", string);
275 if ((idx + 1) < priv->extract.tc_key_extract[tc_id]
282 static inline void dpaa2_flow_qos_entry_log(
283 const char *log_info, const struct rte_flow *flow, int qos_index)
288 if (!dpaa2_flow_control_log)
291 printf("\r\n%s QoS entry[%d] for TC[%d], extracts size is %d\r\n",
292 log_info, qos_index, flow->tc_id, flow->qos_real_key_size);
294 key = (uint8_t *)(size_t)flow->qos_rule.key_iova;
295 mask = (uint8_t *)(size_t)flow->qos_rule.mask_iova;
298 for (idx = 0; idx < flow->qos_real_key_size; idx++)
299 printf("%02x ", key[idx]);
301 printf("\r\nmask:\r\n");
302 for (idx = 0; idx < flow->qos_real_key_size; idx++)
303 printf("%02x ", mask[idx]);
305 printf("\r\n%s QoS ipsrc: %d, ipdst: %d\r\n", log_info,
306 flow->ipaddr_rule.qos_ipsrc_offset,
307 flow->ipaddr_rule.qos_ipdst_offset);
310 static inline void dpaa2_flow_fs_entry_log(
311 const char *log_info, const struct rte_flow *flow)
316 if (!dpaa2_flow_control_log)
319 printf("\r\n%s FS/TC entry[%d] of TC[%d], extracts size is %d\r\n",
320 log_info, flow->tc_index, flow->tc_id, flow->fs_real_key_size);
322 key = (uint8_t *)(size_t)flow->fs_rule.key_iova;
323 mask = (uint8_t *)(size_t)flow->fs_rule.mask_iova;
326 for (idx = 0; idx < flow->fs_real_key_size; idx++)
327 printf("%02x ", key[idx]);
329 printf("\r\nmask:\r\n");
330 for (idx = 0; idx < flow->fs_real_key_size; idx++)
331 printf("%02x ", mask[idx]);
333 printf("\r\n%s FS ipsrc: %d, ipdst: %d\r\n", log_info,
334 flow->ipaddr_rule.fs_ipsrc_offset,
335 flow->ipaddr_rule.fs_ipdst_offset);
338 static inline void dpaa2_flow_extract_key_set(
339 struct dpaa2_key_info *key_info, int index, uint8_t size)
341 key_info->key_size[index] = size;
343 key_info->key_offset[index] =
344 key_info->key_offset[index - 1] +
345 key_info->key_size[index - 1];
347 key_info->key_offset[index] = 0;
349 key_info->key_total_size += size;
352 static int dpaa2_flow_extract_add(
353 struct dpaa2_key_extract *key_extract,
355 uint32_t field, uint8_t field_size)
357 int index, ip_src = -1, ip_dst = -1;
358 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
359 struct dpaa2_key_info *key_info = &key_extract->key_info;
361 if (dpkg->num_extracts >=
362 DPKG_MAX_NUM_OF_EXTRACTS) {
363 DPAA2_PMD_WARN("Number of extracts overflows");
366 /* Before reorder, the IP SRC and IP DST are already last
369 for (index = 0; index < dpkg->num_extracts; index++) {
370 if (dpkg->extracts[index].extract.from_hdr.prot ==
372 if (dpkg->extracts[index].extract.from_hdr.field ==
376 if (dpkg->extracts[index].extract.from_hdr.field ==
384 RTE_ASSERT((ip_src + 2) >= dpkg->num_extracts);
387 RTE_ASSERT((ip_dst + 2) >= dpkg->num_extracts);
389 if (prot == NET_PROT_IP &&
390 (field == NH_FLD_IP_SRC ||
391 field == NH_FLD_IP_DST)) {
392 index = dpkg->num_extracts;
394 if (ip_src >= 0 && ip_dst >= 0)
395 index = dpkg->num_extracts - 2;
396 else if (ip_src >= 0 || ip_dst >= 0)
397 index = dpkg->num_extracts - 1;
399 index = dpkg->num_extracts;
402 dpkg->extracts[index].type = DPKG_EXTRACT_FROM_HDR;
403 dpkg->extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
404 dpkg->extracts[index].extract.from_hdr.prot = prot;
405 dpkg->extracts[index].extract.from_hdr.field = field;
406 if (prot == NET_PROT_IP &&
407 (field == NH_FLD_IP_SRC ||
408 field == NH_FLD_IP_DST)) {
409 dpaa2_flow_extract_key_set(key_info, index, 0);
411 dpaa2_flow_extract_key_set(key_info, index, field_size);
414 if (prot == NET_PROT_IP) {
415 if (field == NH_FLD_IP_SRC) {
416 if (key_info->ipv4_dst_offset >= 0) {
417 key_info->ipv4_src_offset =
418 key_info->ipv4_dst_offset +
419 NH_FLD_IPV4_ADDR_SIZE;
421 key_info->ipv4_src_offset =
422 key_info->key_offset[index - 1] +
423 key_info->key_size[index - 1];
425 if (key_info->ipv6_dst_offset >= 0) {
426 key_info->ipv6_src_offset =
427 key_info->ipv6_dst_offset +
428 NH_FLD_IPV6_ADDR_SIZE;
430 key_info->ipv6_src_offset =
431 key_info->key_offset[index - 1] +
432 key_info->key_size[index - 1];
434 } else if (field == NH_FLD_IP_DST) {
435 if (key_info->ipv4_src_offset >= 0) {
436 key_info->ipv4_dst_offset =
437 key_info->ipv4_src_offset +
438 NH_FLD_IPV4_ADDR_SIZE;
440 key_info->ipv4_dst_offset =
441 key_info->key_offset[index - 1] +
442 key_info->key_size[index - 1];
444 if (key_info->ipv6_src_offset >= 0) {
445 key_info->ipv6_dst_offset =
446 key_info->ipv6_src_offset +
447 NH_FLD_IPV6_ADDR_SIZE;
449 key_info->ipv6_dst_offset =
450 key_info->key_offset[index - 1] +
451 key_info->key_size[index - 1];
456 if (index == dpkg->num_extracts) {
457 dpkg->num_extracts++;
463 dpkg->extracts[ip_src].type =
464 DPKG_EXTRACT_FROM_HDR;
465 dpkg->extracts[ip_src].extract.from_hdr.type =
467 dpkg->extracts[ip_src].extract.from_hdr.prot =
469 dpkg->extracts[ip_src].extract.from_hdr.field =
471 dpaa2_flow_extract_key_set(key_info, ip_src, 0);
472 key_info->ipv4_src_offset += field_size;
473 key_info->ipv6_src_offset += field_size;
477 dpkg->extracts[ip_dst].type =
478 DPKG_EXTRACT_FROM_HDR;
479 dpkg->extracts[ip_dst].extract.from_hdr.type =
481 dpkg->extracts[ip_dst].extract.from_hdr.prot =
483 dpkg->extracts[ip_dst].extract.from_hdr.field =
485 dpaa2_flow_extract_key_set(key_info, ip_dst, 0);
486 key_info->ipv4_dst_offset += field_size;
487 key_info->ipv6_dst_offset += field_size;
490 dpkg->num_extracts++;
495 /* Protocol discrimination.
496 * Discriminate IPv4/IPv6/vLan by Eth type.
497 * Discriminate UDP/TCP/ICMP by next proto of IP.
500 dpaa2_flow_proto_discrimination_extract(
501 struct dpaa2_key_extract *key_extract,
502 enum rte_flow_item_type type)
504 if (type == RTE_FLOW_ITEM_TYPE_ETH) {
505 return dpaa2_flow_extract_add(
506 key_extract, NET_PROT_ETH,
509 } else if (type == (enum rte_flow_item_type)
510 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
511 return dpaa2_flow_extract_add(
512 key_extract, NET_PROT_IP,
514 NH_FLD_IP_PROTO_SIZE);
520 static inline int dpaa2_flow_extract_search(
521 struct dpkg_profile_cfg *dpkg,
522 enum net_prot prot, uint32_t field)
526 for (i = 0; i < dpkg->num_extracts; i++) {
527 if (dpkg->extracts[i].extract.from_hdr.prot == prot &&
528 dpkg->extracts[i].extract.from_hdr.field == field) {
536 static inline int dpaa2_flow_extract_key_offset(
537 struct dpaa2_key_extract *key_extract,
538 enum net_prot prot, uint32_t field)
541 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
542 struct dpaa2_key_info *key_info = &key_extract->key_info;
544 if (prot == NET_PROT_IPV4 ||
545 prot == NET_PROT_IPV6)
546 i = dpaa2_flow_extract_search(dpkg, NET_PROT_IP, field);
548 i = dpaa2_flow_extract_search(dpkg, prot, field);
551 if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_SRC)
552 return key_info->ipv4_src_offset;
553 else if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_DST)
554 return key_info->ipv4_dst_offset;
555 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_SRC)
556 return key_info->ipv6_src_offset;
557 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_DST)
558 return key_info->ipv6_dst_offset;
560 return key_info->key_offset[i];
566 struct proto_discrimination {
567 enum rte_flow_item_type type;
575 dpaa2_flow_proto_discrimination_rule(
576 struct dpaa2_dev_priv *priv, struct rte_flow *flow,
577 struct proto_discrimination proto, int group)
587 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
589 field = NH_FLD_ETH_TYPE;
590 } else if (proto.type == DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
592 field = NH_FLD_IP_PROTO;
595 "Only Eth and IP support to discriminate next proto.");
599 offset = dpaa2_flow_extract_key_offset(&priv->extract.qos_key_extract,
602 DPAA2_PMD_ERR("QoS prot %d field %d extract failed",
606 key_iova = flow->qos_rule.key_iova + offset;
607 mask_iova = flow->qos_rule.mask_iova + offset;
608 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
609 eth_type = proto.eth_type;
610 memcpy((void *)key_iova, (const void *)(ð_type),
613 memcpy((void *)mask_iova, (const void *)(ð_type),
616 ip_proto = proto.ip_proto;
617 memcpy((void *)key_iova, (const void *)(&ip_proto),
620 memcpy((void *)mask_iova, (const void *)(&ip_proto),
624 offset = dpaa2_flow_extract_key_offset(
625 &priv->extract.tc_key_extract[group],
628 DPAA2_PMD_ERR("FS prot %d field %d extract failed",
632 key_iova = flow->fs_rule.key_iova + offset;
633 mask_iova = flow->fs_rule.mask_iova + offset;
635 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
636 eth_type = proto.eth_type;
637 memcpy((void *)key_iova, (const void *)(ð_type),
640 memcpy((void *)mask_iova, (const void *)(ð_type),
643 ip_proto = proto.ip_proto;
644 memcpy((void *)key_iova, (const void *)(&ip_proto),
647 memcpy((void *)mask_iova, (const void *)(&ip_proto),
655 dpaa2_flow_rule_data_set(
656 struct dpaa2_key_extract *key_extract,
657 struct dpni_rule_cfg *rule,
658 enum net_prot prot, uint32_t field,
659 const void *key, const void *mask, int size)
661 int offset = dpaa2_flow_extract_key_offset(key_extract,
665 DPAA2_PMD_ERR("prot %d, field %d extract failed",
670 memcpy((void *)(size_t)(rule->key_iova + offset), key, size);
671 memcpy((void *)(size_t)(rule->mask_iova + offset), mask, size);
677 _dpaa2_flow_rule_move_ipaddr_tail(
678 struct dpaa2_key_extract *key_extract,
679 struct dpni_rule_cfg *rule, int src_offset,
680 uint32_t field, bool ipv4)
688 char tmp[NH_FLD_IPV6_ADDR_SIZE];
690 if (field != NH_FLD_IP_SRC &&
691 field != NH_FLD_IP_DST) {
692 DPAA2_PMD_ERR("Field of IP addr reorder must be IP SRC/DST");
696 prot = NET_PROT_IPV4;
698 prot = NET_PROT_IPV6;
699 dst_offset = dpaa2_flow_extract_key_offset(key_extract,
701 if (dst_offset < 0) {
702 DPAA2_PMD_ERR("Field %d reorder extract failed", field);
705 key_src = rule->key_iova + src_offset;
706 mask_src = rule->mask_iova + src_offset;
707 key_dst = rule->key_iova + dst_offset;
708 mask_dst = rule->mask_iova + dst_offset;
710 len = sizeof(rte_be32_t);
712 len = NH_FLD_IPV6_ADDR_SIZE;
714 memcpy(tmp, (char *)key_src, len);
715 memset((char *)key_src, 0, len);
716 memcpy((char *)key_dst, tmp, len);
718 memcpy(tmp, (char *)mask_src, len);
719 memset((char *)mask_src, 0, len);
720 memcpy((char *)mask_dst, tmp, len);
726 dpaa2_flow_rule_move_ipaddr_tail(
727 struct rte_flow *flow, struct dpaa2_dev_priv *priv,
733 if (flow->ipaddr_rule.ipaddr_type == FLOW_NONE_IPADDR)
736 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR)
737 prot = NET_PROT_IPV4;
739 prot = NET_PROT_IPV6;
741 if (flow->ipaddr_rule.qos_ipsrc_offset >= 0) {
742 ret = _dpaa2_flow_rule_move_ipaddr_tail(
743 &priv->extract.qos_key_extract,
745 flow->ipaddr_rule.qos_ipsrc_offset,
746 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
748 DPAA2_PMD_ERR("QoS src address reorder failed");
751 flow->ipaddr_rule.qos_ipsrc_offset =
752 dpaa2_flow_extract_key_offset(
753 &priv->extract.qos_key_extract,
754 prot, NH_FLD_IP_SRC);
757 if (flow->ipaddr_rule.qos_ipdst_offset >= 0) {
758 ret = _dpaa2_flow_rule_move_ipaddr_tail(
759 &priv->extract.qos_key_extract,
761 flow->ipaddr_rule.qos_ipdst_offset,
762 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
764 DPAA2_PMD_ERR("QoS dst address reorder failed");
767 flow->ipaddr_rule.qos_ipdst_offset =
768 dpaa2_flow_extract_key_offset(
769 &priv->extract.qos_key_extract,
770 prot, NH_FLD_IP_DST);
773 if (flow->ipaddr_rule.fs_ipsrc_offset >= 0) {
774 ret = _dpaa2_flow_rule_move_ipaddr_tail(
775 &priv->extract.tc_key_extract[fs_group],
777 flow->ipaddr_rule.fs_ipsrc_offset,
778 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
780 DPAA2_PMD_ERR("FS src address reorder failed");
783 flow->ipaddr_rule.fs_ipsrc_offset =
784 dpaa2_flow_extract_key_offset(
785 &priv->extract.tc_key_extract[fs_group],
786 prot, NH_FLD_IP_SRC);
788 if (flow->ipaddr_rule.fs_ipdst_offset >= 0) {
789 ret = _dpaa2_flow_rule_move_ipaddr_tail(
790 &priv->extract.tc_key_extract[fs_group],
792 flow->ipaddr_rule.fs_ipdst_offset,
793 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
795 DPAA2_PMD_ERR("FS dst address reorder failed");
798 flow->ipaddr_rule.fs_ipdst_offset =
799 dpaa2_flow_extract_key_offset(
800 &priv->extract.tc_key_extract[fs_group],
801 prot, NH_FLD_IP_DST);
808 dpaa2_flow_extract_support(
809 const uint8_t *mask_src,
810 enum rte_flow_item_type type)
814 const char *mask_support = 0;
817 case RTE_FLOW_ITEM_TYPE_ETH:
818 mask_support = (const char *)&dpaa2_flow_item_eth_mask;
819 size = sizeof(struct rte_flow_item_eth);
821 case RTE_FLOW_ITEM_TYPE_VLAN:
822 mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
823 size = sizeof(struct rte_flow_item_vlan);
825 case RTE_FLOW_ITEM_TYPE_IPV4:
826 mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
827 size = sizeof(struct rte_flow_item_ipv4);
829 case RTE_FLOW_ITEM_TYPE_IPV6:
830 mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
831 size = sizeof(struct rte_flow_item_ipv6);
833 case RTE_FLOW_ITEM_TYPE_ICMP:
834 mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
835 size = sizeof(struct rte_flow_item_icmp);
837 case RTE_FLOW_ITEM_TYPE_UDP:
838 mask_support = (const char *)&dpaa2_flow_item_udp_mask;
839 size = sizeof(struct rte_flow_item_udp);
841 case RTE_FLOW_ITEM_TYPE_TCP:
842 mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
843 size = sizeof(struct rte_flow_item_tcp);
845 case RTE_FLOW_ITEM_TYPE_SCTP:
846 mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
847 size = sizeof(struct rte_flow_item_sctp);
849 case RTE_FLOW_ITEM_TYPE_GRE:
850 mask_support = (const char *)&dpaa2_flow_item_gre_mask;
851 size = sizeof(struct rte_flow_item_gre);
857 memcpy(mask, mask_support, size);
859 for (i = 0; i < size; i++)
860 mask[i] = (mask[i] | mask_src[i]);
862 if (memcmp(mask, mask_support, size))
869 dpaa2_configure_flow_eth(struct rte_flow *flow,
870 struct rte_eth_dev *dev,
871 const struct rte_flow_attr *attr,
872 const struct rte_flow_item *pattern,
873 const struct rte_flow_action actions[] __rte_unused,
874 struct rte_flow_error *error __rte_unused,
875 int *device_configured)
880 const struct rte_flow_item_eth *spec, *mask;
882 /* TODO: Currently upper bound of range parameter is not implemented */
883 const struct rte_flow_item_eth *last __rte_unused;
884 struct dpaa2_dev_priv *priv = dev->data->dev_private;
885 const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
889 /* Parse pattern list to get the matching parameters */
890 spec = (const struct rte_flow_item_eth *)pattern->spec;
891 last = (const struct rte_flow_item_eth *)pattern->last;
892 mask = (const struct rte_flow_item_eth *)
893 (pattern->mask ? pattern->mask : &dpaa2_flow_item_eth_mask);
895 /* Don't care any field of eth header,
896 * only care eth protocol.
898 DPAA2_PMD_WARN("No pattern spec for Eth flow, just skip");
902 /* Get traffic class index and flow id to be configured */
904 flow->tc_index = attr->priority;
906 if (dpaa2_flow_extract_support((const uint8_t *)mask,
907 RTE_FLOW_ITEM_TYPE_ETH)) {
908 DPAA2_PMD_WARN("Extract field(s) of ethernet not support.");
913 if (memcmp((const char *)&mask->src, zero_cmp, RTE_ETHER_ADDR_LEN)) {
914 index = dpaa2_flow_extract_search(
915 &priv->extract.qos_key_extract.dpkg,
916 NET_PROT_ETH, NH_FLD_ETH_SA);
918 ret = dpaa2_flow_extract_add(
919 &priv->extract.qos_key_extract,
920 NET_PROT_ETH, NH_FLD_ETH_SA,
923 DPAA2_PMD_ERR("QoS Extract add ETH_SA failed.");
927 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
929 index = dpaa2_flow_extract_search(
930 &priv->extract.tc_key_extract[group].dpkg,
931 NET_PROT_ETH, NH_FLD_ETH_SA);
933 ret = dpaa2_flow_extract_add(
934 &priv->extract.tc_key_extract[group],
935 NET_PROT_ETH, NH_FLD_ETH_SA,
938 DPAA2_PMD_ERR("FS Extract add ETH_SA failed.");
941 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
944 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
947 "Move ipaddr before ETH_SA rule set failed");
951 ret = dpaa2_flow_rule_data_set(
952 &priv->extract.qos_key_extract,
956 &spec->src.addr_bytes,
957 &mask->src.addr_bytes,
958 sizeof(struct rte_ether_addr));
960 DPAA2_PMD_ERR("QoS NH_FLD_ETH_SA rule data set failed");
964 ret = dpaa2_flow_rule_data_set(
965 &priv->extract.tc_key_extract[group],
969 &spec->src.addr_bytes,
970 &mask->src.addr_bytes,
971 sizeof(struct rte_ether_addr));
973 DPAA2_PMD_ERR("FS NH_FLD_ETH_SA rule data set failed");
978 if (memcmp((const char *)&mask->dst, zero_cmp, RTE_ETHER_ADDR_LEN)) {
979 index = dpaa2_flow_extract_search(
980 &priv->extract.qos_key_extract.dpkg,
981 NET_PROT_ETH, NH_FLD_ETH_DA);
983 ret = dpaa2_flow_extract_add(
984 &priv->extract.qos_key_extract,
985 NET_PROT_ETH, NH_FLD_ETH_DA,
988 DPAA2_PMD_ERR("QoS Extract add ETH_DA failed.");
992 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
995 index = dpaa2_flow_extract_search(
996 &priv->extract.tc_key_extract[group].dpkg,
997 NET_PROT_ETH, NH_FLD_ETH_DA);
999 ret = dpaa2_flow_extract_add(
1000 &priv->extract.tc_key_extract[group],
1001 NET_PROT_ETH, NH_FLD_ETH_DA,
1002 RTE_ETHER_ADDR_LEN);
1004 DPAA2_PMD_ERR("FS Extract add ETH_DA failed.");
1008 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1011 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1014 "Move ipaddr before ETH DA rule set failed");
1018 ret = dpaa2_flow_rule_data_set(
1019 &priv->extract.qos_key_extract,
1023 &spec->dst.addr_bytes,
1024 &mask->dst.addr_bytes,
1025 sizeof(struct rte_ether_addr));
1027 DPAA2_PMD_ERR("QoS NH_FLD_ETH_DA rule data set failed");
1031 ret = dpaa2_flow_rule_data_set(
1032 &priv->extract.tc_key_extract[group],
1036 &spec->dst.addr_bytes,
1037 &mask->dst.addr_bytes,
1038 sizeof(struct rte_ether_addr));
1040 DPAA2_PMD_ERR("FS NH_FLD_ETH_DA rule data set failed");
1045 if (memcmp((const char *)&mask->type, zero_cmp, sizeof(rte_be16_t))) {
1046 index = dpaa2_flow_extract_search(
1047 &priv->extract.qos_key_extract.dpkg,
1048 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1050 ret = dpaa2_flow_extract_add(
1051 &priv->extract.qos_key_extract,
1052 NET_PROT_ETH, NH_FLD_ETH_TYPE,
1053 RTE_ETHER_TYPE_LEN);
1055 DPAA2_PMD_ERR("QoS Extract add ETH_TYPE failed.");
1059 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1061 index = dpaa2_flow_extract_search(
1062 &priv->extract.tc_key_extract[group].dpkg,
1063 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1065 ret = dpaa2_flow_extract_add(
1066 &priv->extract.tc_key_extract[group],
1067 NET_PROT_ETH, NH_FLD_ETH_TYPE,
1068 RTE_ETHER_TYPE_LEN);
1070 DPAA2_PMD_ERR("FS Extract add ETH_TYPE failed.");
1074 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1077 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1080 "Move ipaddr before ETH TYPE rule set failed");
1084 ret = dpaa2_flow_rule_data_set(
1085 &priv->extract.qos_key_extract,
1091 sizeof(rte_be16_t));
1093 DPAA2_PMD_ERR("QoS NH_FLD_ETH_TYPE rule data set failed");
1097 ret = dpaa2_flow_rule_data_set(
1098 &priv->extract.tc_key_extract[group],
1104 sizeof(rte_be16_t));
1106 DPAA2_PMD_ERR("FS NH_FLD_ETH_TYPE rule data set failed");
1111 (*device_configured) |= local_cfg;
1117 dpaa2_configure_flow_vlan(struct rte_flow *flow,
1118 struct rte_eth_dev *dev,
1119 const struct rte_flow_attr *attr,
1120 const struct rte_flow_item *pattern,
1121 const struct rte_flow_action actions[] __rte_unused,
1122 struct rte_flow_error *error __rte_unused,
1123 int *device_configured)
1128 const struct rte_flow_item_vlan *spec, *mask;
1130 const struct rte_flow_item_vlan *last __rte_unused;
1131 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1133 group = attr->group;
1135 /* Parse pattern list to get the matching parameters */
1136 spec = (const struct rte_flow_item_vlan *)pattern->spec;
1137 last = (const struct rte_flow_item_vlan *)pattern->last;
1138 mask = (const struct rte_flow_item_vlan *)
1139 (pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask);
1141 /* Get traffic class index and flow id to be configured */
1142 flow->tc_id = group;
1143 flow->tc_index = attr->priority;
1146 /* Don't care any field of vlan header,
1147 * only care vlan protocol.
1149 /* Eth type is actually used for vLan classification.
1151 struct proto_discrimination proto;
1153 index = dpaa2_flow_extract_search(
1154 &priv->extract.qos_key_extract.dpkg,
1155 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1157 ret = dpaa2_flow_proto_discrimination_extract(
1158 &priv->extract.qos_key_extract,
1159 RTE_FLOW_ITEM_TYPE_ETH);
1162 "QoS Ext ETH_TYPE to discriminate vLan failed");
1166 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1169 index = dpaa2_flow_extract_search(
1170 &priv->extract.tc_key_extract[group].dpkg,
1171 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1173 ret = dpaa2_flow_proto_discrimination_extract(
1174 &priv->extract.tc_key_extract[group],
1175 RTE_FLOW_ITEM_TYPE_ETH);
1178 "FS Ext ETH_TYPE to discriminate vLan failed.");
1182 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1185 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1188 "Move ipaddr before vLan discrimination set failed");
1192 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1193 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
1194 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1197 DPAA2_PMD_ERR("vLan discrimination rule set failed");
1201 (*device_configured) |= local_cfg;
1206 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1207 RTE_FLOW_ITEM_TYPE_VLAN)) {
1208 DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
1216 index = dpaa2_flow_extract_search(
1217 &priv->extract.qos_key_extract.dpkg,
1218 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1220 ret = dpaa2_flow_extract_add(
1221 &priv->extract.qos_key_extract,
1224 sizeof(rte_be16_t));
1226 DPAA2_PMD_ERR("QoS Extract add VLAN_TCI failed.");
1230 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1233 index = dpaa2_flow_extract_search(
1234 &priv->extract.tc_key_extract[group].dpkg,
1235 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1237 ret = dpaa2_flow_extract_add(
1238 &priv->extract.tc_key_extract[group],
1241 sizeof(rte_be16_t));
1243 DPAA2_PMD_ERR("FS Extract add VLAN_TCI failed.");
1247 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1250 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1253 "Move ipaddr before VLAN TCI rule set failed");
1257 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
1263 sizeof(rte_be16_t));
1265 DPAA2_PMD_ERR("QoS NH_FLD_VLAN_TCI rule data set failed");
1269 ret = dpaa2_flow_rule_data_set(
1270 &priv->extract.tc_key_extract[group],
1276 sizeof(rte_be16_t));
1278 DPAA2_PMD_ERR("FS NH_FLD_VLAN_TCI rule data set failed");
1282 (*device_configured) |= local_cfg;
1288 dpaa2_configure_flow_ip_discrimation(
1289 struct dpaa2_dev_priv *priv, struct rte_flow *flow,
1290 const struct rte_flow_item *pattern,
1291 int *local_cfg, int *device_configured,
1295 struct proto_discrimination proto;
1297 index = dpaa2_flow_extract_search(
1298 &priv->extract.qos_key_extract.dpkg,
1299 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1301 ret = dpaa2_flow_proto_discrimination_extract(
1302 &priv->extract.qos_key_extract,
1303 RTE_FLOW_ITEM_TYPE_ETH);
1306 "QoS Extract ETH_TYPE to discriminate IP failed.");
1309 (*local_cfg) |= DPAA2_QOS_TABLE_RECONFIGURE;
1312 index = dpaa2_flow_extract_search(
1313 &priv->extract.tc_key_extract[group].dpkg,
1314 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1316 ret = dpaa2_flow_proto_discrimination_extract(
1317 &priv->extract.tc_key_extract[group],
1318 RTE_FLOW_ITEM_TYPE_ETH);
1321 "FS Extract ETH_TYPE to discriminate IP failed.");
1324 (*local_cfg) |= DPAA2_FS_TABLE_RECONFIGURE;
1327 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1330 "Move ipaddr before IP discrimination set failed");
1334 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1335 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4)
1336 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
1338 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
1339 ret = dpaa2_flow_proto_discrimination_rule(priv, flow, proto, group);
1341 DPAA2_PMD_ERR("IP discrimination rule set failed");
1345 (*device_configured) |= (*local_cfg);
1352 dpaa2_configure_flow_generic_ip(
1353 struct rte_flow *flow,
1354 struct rte_eth_dev *dev,
1355 const struct rte_flow_attr *attr,
1356 const struct rte_flow_item *pattern,
1357 const struct rte_flow_action actions[] __rte_unused,
1358 struct rte_flow_error *error __rte_unused,
1359 int *device_configured)
1364 const struct rte_flow_item_ipv4 *spec_ipv4 = 0,
1366 const struct rte_flow_item_ipv6 *spec_ipv6 = 0,
1368 const void *key, *mask;
1371 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1372 const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
1375 group = attr->group;
1377 /* Parse pattern list to get the matching parameters */
1378 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1379 spec_ipv4 = (const struct rte_flow_item_ipv4 *)pattern->spec;
1380 mask_ipv4 = (const struct rte_flow_item_ipv4 *)
1381 (pattern->mask ? pattern->mask :
1382 &dpaa2_flow_item_ipv4_mask);
1384 spec_ipv6 = (const struct rte_flow_item_ipv6 *)pattern->spec;
1385 mask_ipv6 = (const struct rte_flow_item_ipv6 *)
1386 (pattern->mask ? pattern->mask :
1387 &dpaa2_flow_item_ipv6_mask);
1390 /* Get traffic class index and flow id to be configured */
1391 flow->tc_id = group;
1392 flow->tc_index = attr->priority;
1394 ret = dpaa2_configure_flow_ip_discrimation(priv,
1395 flow, pattern, &local_cfg,
1396 device_configured, group);
1398 DPAA2_PMD_ERR("IP discrimation failed!");
1402 if (!spec_ipv4 && !spec_ipv6)
1406 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
1407 RTE_FLOW_ITEM_TYPE_IPV4)) {
1408 DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
1415 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
1416 RTE_FLOW_ITEM_TYPE_IPV6)) {
1417 DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
1423 if (mask_ipv4 && (mask_ipv4->hdr.src_addr ||
1424 mask_ipv4->hdr.dst_addr)) {
1425 flow->ipaddr_rule.ipaddr_type = FLOW_IPV4_ADDR;
1426 } else if (mask_ipv6 &&
1427 (memcmp((const char *)mask_ipv6->hdr.src_addr,
1428 zero_cmp, NH_FLD_IPV6_ADDR_SIZE) ||
1429 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1430 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1431 flow->ipaddr_rule.ipaddr_type = FLOW_IPV6_ADDR;
1434 if ((mask_ipv4 && mask_ipv4->hdr.src_addr) ||
1436 memcmp((const char *)mask_ipv6->hdr.src_addr,
1437 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1438 index = dpaa2_flow_extract_search(
1439 &priv->extract.qos_key_extract.dpkg,
1440 NET_PROT_IP, NH_FLD_IP_SRC);
1442 ret = dpaa2_flow_extract_add(
1443 &priv->extract.qos_key_extract,
1448 DPAA2_PMD_ERR("QoS Extract add IP_SRC failed.");
1452 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1455 index = dpaa2_flow_extract_search(
1456 &priv->extract.tc_key_extract[group].dpkg,
1457 NET_PROT_IP, NH_FLD_IP_SRC);
1459 ret = dpaa2_flow_extract_add(
1460 &priv->extract.tc_key_extract[group],
1465 DPAA2_PMD_ERR("FS Extract add IP_SRC failed.");
1469 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1473 key = &spec_ipv4->hdr.src_addr;
1475 key = &spec_ipv6->hdr.src_addr[0];
1477 mask = &mask_ipv4->hdr.src_addr;
1478 size = NH_FLD_IPV4_ADDR_SIZE;
1479 prot = NET_PROT_IPV4;
1481 mask = &mask_ipv6->hdr.src_addr[0];
1482 size = NH_FLD_IPV6_ADDR_SIZE;
1483 prot = NET_PROT_IPV6;
1486 ret = dpaa2_flow_rule_data_set(
1487 &priv->extract.qos_key_extract,
1489 prot, NH_FLD_IP_SRC,
1492 DPAA2_PMD_ERR("QoS NH_FLD_IP_SRC rule data set failed");
1496 ret = dpaa2_flow_rule_data_set(
1497 &priv->extract.tc_key_extract[group],
1499 prot, NH_FLD_IP_SRC,
1502 DPAA2_PMD_ERR("FS NH_FLD_IP_SRC rule data set failed");
1506 flow->ipaddr_rule.qos_ipsrc_offset =
1507 dpaa2_flow_extract_key_offset(
1508 &priv->extract.qos_key_extract,
1509 prot, NH_FLD_IP_SRC);
1510 flow->ipaddr_rule.fs_ipsrc_offset =
1511 dpaa2_flow_extract_key_offset(
1512 &priv->extract.tc_key_extract[group],
1513 prot, NH_FLD_IP_SRC);
1516 if ((mask_ipv4 && mask_ipv4->hdr.dst_addr) ||
1518 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1519 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1520 index = dpaa2_flow_extract_search(
1521 &priv->extract.qos_key_extract.dpkg,
1522 NET_PROT_IP, NH_FLD_IP_DST);
1525 size = NH_FLD_IPV4_ADDR_SIZE;
1527 size = NH_FLD_IPV6_ADDR_SIZE;
1528 ret = dpaa2_flow_extract_add(
1529 &priv->extract.qos_key_extract,
1534 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1538 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1541 index = dpaa2_flow_extract_search(
1542 &priv->extract.tc_key_extract[group].dpkg,
1543 NET_PROT_IP, NH_FLD_IP_DST);
1546 size = NH_FLD_IPV4_ADDR_SIZE;
1548 size = NH_FLD_IPV6_ADDR_SIZE;
1549 ret = dpaa2_flow_extract_add(
1550 &priv->extract.tc_key_extract[group],
1555 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1559 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1563 key = &spec_ipv4->hdr.dst_addr;
1565 key = spec_ipv6->hdr.dst_addr;
1567 mask = &mask_ipv4->hdr.dst_addr;
1568 size = NH_FLD_IPV4_ADDR_SIZE;
1569 prot = NET_PROT_IPV4;
1571 mask = &mask_ipv6->hdr.dst_addr[0];
1572 size = NH_FLD_IPV6_ADDR_SIZE;
1573 prot = NET_PROT_IPV6;
1576 ret = dpaa2_flow_rule_data_set(
1577 &priv->extract.qos_key_extract,
1579 prot, NH_FLD_IP_DST,
1582 DPAA2_PMD_ERR("QoS NH_FLD_IP_DST rule data set failed");
1586 ret = dpaa2_flow_rule_data_set(
1587 &priv->extract.tc_key_extract[group],
1589 prot, NH_FLD_IP_DST,
1592 DPAA2_PMD_ERR("FS NH_FLD_IP_DST rule data set failed");
1595 flow->ipaddr_rule.qos_ipdst_offset =
1596 dpaa2_flow_extract_key_offset(
1597 &priv->extract.qos_key_extract,
1598 prot, NH_FLD_IP_DST);
1599 flow->ipaddr_rule.fs_ipdst_offset =
1600 dpaa2_flow_extract_key_offset(
1601 &priv->extract.tc_key_extract[group],
1602 prot, NH_FLD_IP_DST);
1605 if ((mask_ipv4 && mask_ipv4->hdr.next_proto_id) ||
1606 (mask_ipv6 && mask_ipv6->hdr.proto)) {
1607 index = dpaa2_flow_extract_search(
1608 &priv->extract.qos_key_extract.dpkg,
1609 NET_PROT_IP, NH_FLD_IP_PROTO);
1611 ret = dpaa2_flow_extract_add(
1612 &priv->extract.qos_key_extract,
1615 NH_FLD_IP_PROTO_SIZE);
1617 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1621 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1624 index = dpaa2_flow_extract_search(
1625 &priv->extract.tc_key_extract[group].dpkg,
1626 NET_PROT_IP, NH_FLD_IP_PROTO);
1628 ret = dpaa2_flow_extract_add(
1629 &priv->extract.tc_key_extract[group],
1632 NH_FLD_IP_PROTO_SIZE);
1634 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1638 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1641 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1644 "Move ipaddr after NH_FLD_IP_PROTO rule set failed");
1649 key = &spec_ipv4->hdr.next_proto_id;
1651 key = &spec_ipv6->hdr.proto;
1653 mask = &mask_ipv4->hdr.next_proto_id;
1655 mask = &mask_ipv6->hdr.proto;
1657 ret = dpaa2_flow_rule_data_set(
1658 &priv->extract.qos_key_extract,
1662 key, mask, NH_FLD_IP_PROTO_SIZE);
1664 DPAA2_PMD_ERR("QoS NH_FLD_IP_PROTO rule data set failed");
1668 ret = dpaa2_flow_rule_data_set(
1669 &priv->extract.tc_key_extract[group],
1673 key, mask, NH_FLD_IP_PROTO_SIZE);
1675 DPAA2_PMD_ERR("FS NH_FLD_IP_PROTO rule data set failed");
1680 (*device_configured) |= local_cfg;
1686 dpaa2_configure_flow_icmp(struct rte_flow *flow,
1687 struct rte_eth_dev *dev,
1688 const struct rte_flow_attr *attr,
1689 const struct rte_flow_item *pattern,
1690 const struct rte_flow_action actions[] __rte_unused,
1691 struct rte_flow_error *error __rte_unused,
1692 int *device_configured)
1697 const struct rte_flow_item_icmp *spec, *mask;
1699 const struct rte_flow_item_icmp *last __rte_unused;
1700 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1702 group = attr->group;
1704 /* Parse pattern list to get the matching parameters */
1705 spec = (const struct rte_flow_item_icmp *)pattern->spec;
1706 last = (const struct rte_flow_item_icmp *)pattern->last;
1707 mask = (const struct rte_flow_item_icmp *)
1708 (pattern->mask ? pattern->mask : &dpaa2_flow_item_icmp_mask);
1710 /* Get traffic class index and flow id to be configured */
1711 flow->tc_id = group;
1712 flow->tc_index = attr->priority;
1715 /* Don't care any field of ICMP header,
1716 * only care ICMP protocol.
1717 * Example: flow create 0 ingress pattern icmp /
1719 /* Next proto of Generical IP is actually used
1720 * for ICMP identification.
1722 struct proto_discrimination proto;
1724 index = dpaa2_flow_extract_search(
1725 &priv->extract.qos_key_extract.dpkg,
1726 NET_PROT_IP, NH_FLD_IP_PROTO);
1728 ret = dpaa2_flow_proto_discrimination_extract(
1729 &priv->extract.qos_key_extract,
1730 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1733 "QoS Extract IP protocol to discriminate ICMP failed.");
1737 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1740 index = dpaa2_flow_extract_search(
1741 &priv->extract.tc_key_extract[group].dpkg,
1742 NET_PROT_IP, NH_FLD_IP_PROTO);
1744 ret = dpaa2_flow_proto_discrimination_extract(
1745 &priv->extract.tc_key_extract[group],
1746 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1749 "FS Extract IP protocol to discriminate ICMP failed.");
1753 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1756 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1759 "Move IP addr before ICMP discrimination set failed");
1763 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1764 proto.ip_proto = IPPROTO_ICMP;
1765 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1768 DPAA2_PMD_ERR("ICMP discrimination rule set failed");
1772 (*device_configured) |= local_cfg;
1777 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1778 RTE_FLOW_ITEM_TYPE_ICMP)) {
1779 DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
1784 if (mask->hdr.icmp_type) {
1785 index = dpaa2_flow_extract_search(
1786 &priv->extract.qos_key_extract.dpkg,
1787 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1789 ret = dpaa2_flow_extract_add(
1790 &priv->extract.qos_key_extract,
1793 NH_FLD_ICMP_TYPE_SIZE);
1795 DPAA2_PMD_ERR("QoS Extract add ICMP_TYPE failed.");
1799 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1802 index = dpaa2_flow_extract_search(
1803 &priv->extract.tc_key_extract[group].dpkg,
1804 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1806 ret = dpaa2_flow_extract_add(
1807 &priv->extract.tc_key_extract[group],
1810 NH_FLD_ICMP_TYPE_SIZE);
1812 DPAA2_PMD_ERR("FS Extract add ICMP_TYPE failed.");
1816 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1819 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1822 "Move ipaddr before ICMP TYPE set failed");
1826 ret = dpaa2_flow_rule_data_set(
1827 &priv->extract.qos_key_extract,
1831 &spec->hdr.icmp_type,
1832 &mask->hdr.icmp_type,
1833 NH_FLD_ICMP_TYPE_SIZE);
1835 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_TYPE rule data set failed");
1839 ret = dpaa2_flow_rule_data_set(
1840 &priv->extract.tc_key_extract[group],
1844 &spec->hdr.icmp_type,
1845 &mask->hdr.icmp_type,
1846 NH_FLD_ICMP_TYPE_SIZE);
1848 DPAA2_PMD_ERR("FS NH_FLD_ICMP_TYPE rule data set failed");
1853 if (mask->hdr.icmp_code) {
1854 index = dpaa2_flow_extract_search(
1855 &priv->extract.qos_key_extract.dpkg,
1856 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1858 ret = dpaa2_flow_extract_add(
1859 &priv->extract.qos_key_extract,
1862 NH_FLD_ICMP_CODE_SIZE);
1864 DPAA2_PMD_ERR("QoS Extract add ICMP_CODE failed.");
1868 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1871 index = dpaa2_flow_extract_search(
1872 &priv->extract.tc_key_extract[group].dpkg,
1873 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1875 ret = dpaa2_flow_extract_add(
1876 &priv->extract.tc_key_extract[group],
1879 NH_FLD_ICMP_CODE_SIZE);
1881 DPAA2_PMD_ERR("FS Extract add ICMP_CODE failed.");
1885 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1888 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1891 "Move ipaddr after ICMP CODE set failed");
1895 ret = dpaa2_flow_rule_data_set(
1896 &priv->extract.qos_key_extract,
1900 &spec->hdr.icmp_code,
1901 &mask->hdr.icmp_code,
1902 NH_FLD_ICMP_CODE_SIZE);
1904 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_CODE rule data set failed");
1908 ret = dpaa2_flow_rule_data_set(
1909 &priv->extract.tc_key_extract[group],
1913 &spec->hdr.icmp_code,
1914 &mask->hdr.icmp_code,
1915 NH_FLD_ICMP_CODE_SIZE);
1917 DPAA2_PMD_ERR("FS NH_FLD_ICMP_CODE rule data set failed");
1922 (*device_configured) |= local_cfg;
1928 dpaa2_configure_flow_udp(struct rte_flow *flow,
1929 struct rte_eth_dev *dev,
1930 const struct rte_flow_attr *attr,
1931 const struct rte_flow_item *pattern,
1932 const struct rte_flow_action actions[] __rte_unused,
1933 struct rte_flow_error *error __rte_unused,
1934 int *device_configured)
1939 const struct rte_flow_item_udp *spec, *mask;
1941 const struct rte_flow_item_udp *last __rte_unused;
1942 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1944 group = attr->group;
1946 /* Parse pattern list to get the matching parameters */
1947 spec = (const struct rte_flow_item_udp *)pattern->spec;
1948 last = (const struct rte_flow_item_udp *)pattern->last;
1949 mask = (const struct rte_flow_item_udp *)
1950 (pattern->mask ? pattern->mask : &dpaa2_flow_item_udp_mask);
1952 /* Get traffic class index and flow id to be configured */
1953 flow->tc_id = group;
1954 flow->tc_index = attr->priority;
1956 if (!spec || !mc_l4_port_identification) {
1957 struct proto_discrimination proto;
1959 index = dpaa2_flow_extract_search(
1960 &priv->extract.qos_key_extract.dpkg,
1961 NET_PROT_IP, NH_FLD_IP_PROTO);
1963 ret = dpaa2_flow_proto_discrimination_extract(
1964 &priv->extract.qos_key_extract,
1965 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1968 "QoS Extract IP protocol to discriminate UDP failed.");
1972 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1975 index = dpaa2_flow_extract_search(
1976 &priv->extract.tc_key_extract[group].dpkg,
1977 NET_PROT_IP, NH_FLD_IP_PROTO);
1979 ret = dpaa2_flow_proto_discrimination_extract(
1980 &priv->extract.tc_key_extract[group],
1981 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1984 "FS Extract IP protocol to discriminate UDP failed.");
1988 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1991 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1994 "Move IP addr before UDP discrimination set failed");
1998 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1999 proto.ip_proto = IPPROTO_UDP;
2000 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2003 DPAA2_PMD_ERR("UDP discrimination rule set failed");
2007 (*device_configured) |= local_cfg;
2013 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2014 RTE_FLOW_ITEM_TYPE_UDP)) {
2015 DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
2020 if (mask->hdr.src_port) {
2021 index = dpaa2_flow_extract_search(
2022 &priv->extract.qos_key_extract.dpkg,
2023 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
2025 ret = dpaa2_flow_extract_add(
2026 &priv->extract.qos_key_extract,
2028 NH_FLD_UDP_PORT_SRC,
2029 NH_FLD_UDP_PORT_SIZE);
2031 DPAA2_PMD_ERR("QoS Extract add UDP_SRC failed.");
2035 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2038 index = dpaa2_flow_extract_search(
2039 &priv->extract.tc_key_extract[group].dpkg,
2040 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
2042 ret = dpaa2_flow_extract_add(
2043 &priv->extract.tc_key_extract[group],
2045 NH_FLD_UDP_PORT_SRC,
2046 NH_FLD_UDP_PORT_SIZE);
2048 DPAA2_PMD_ERR("FS Extract add UDP_SRC failed.");
2052 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2055 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2058 "Move ipaddr before UDP_PORT_SRC set failed");
2062 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
2065 NH_FLD_UDP_PORT_SRC,
2066 &spec->hdr.src_port,
2067 &mask->hdr.src_port,
2068 NH_FLD_UDP_PORT_SIZE);
2071 "QoS NH_FLD_UDP_PORT_SRC rule data set failed");
2075 ret = dpaa2_flow_rule_data_set(
2076 &priv->extract.tc_key_extract[group],
2079 NH_FLD_UDP_PORT_SRC,
2080 &spec->hdr.src_port,
2081 &mask->hdr.src_port,
2082 NH_FLD_UDP_PORT_SIZE);
2085 "FS NH_FLD_UDP_PORT_SRC rule data set failed");
2090 if (mask->hdr.dst_port) {
2091 index = dpaa2_flow_extract_search(
2092 &priv->extract.qos_key_extract.dpkg,
2093 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
2095 ret = dpaa2_flow_extract_add(
2096 &priv->extract.qos_key_extract,
2098 NH_FLD_UDP_PORT_DST,
2099 NH_FLD_UDP_PORT_SIZE);
2101 DPAA2_PMD_ERR("QoS Extract add UDP_DST failed.");
2105 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2108 index = dpaa2_flow_extract_search(
2109 &priv->extract.tc_key_extract[group].dpkg,
2110 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
2112 ret = dpaa2_flow_extract_add(
2113 &priv->extract.tc_key_extract[group],
2115 NH_FLD_UDP_PORT_DST,
2116 NH_FLD_UDP_PORT_SIZE);
2118 DPAA2_PMD_ERR("FS Extract add UDP_DST failed.");
2122 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2125 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2128 "Move ipaddr before UDP_PORT_DST set failed");
2132 ret = dpaa2_flow_rule_data_set(
2133 &priv->extract.qos_key_extract,
2136 NH_FLD_UDP_PORT_DST,
2137 &spec->hdr.dst_port,
2138 &mask->hdr.dst_port,
2139 NH_FLD_UDP_PORT_SIZE);
2142 "QoS NH_FLD_UDP_PORT_DST rule data set failed");
2146 ret = dpaa2_flow_rule_data_set(
2147 &priv->extract.tc_key_extract[group],
2150 NH_FLD_UDP_PORT_DST,
2151 &spec->hdr.dst_port,
2152 &mask->hdr.dst_port,
2153 NH_FLD_UDP_PORT_SIZE);
2156 "FS NH_FLD_UDP_PORT_DST rule data set failed");
2161 (*device_configured) |= local_cfg;
2167 dpaa2_configure_flow_tcp(struct rte_flow *flow,
2168 struct rte_eth_dev *dev,
2169 const struct rte_flow_attr *attr,
2170 const struct rte_flow_item *pattern,
2171 const struct rte_flow_action actions[] __rte_unused,
2172 struct rte_flow_error *error __rte_unused,
2173 int *device_configured)
2178 const struct rte_flow_item_tcp *spec, *mask;
2180 const struct rte_flow_item_tcp *last __rte_unused;
2181 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2183 group = attr->group;
2185 /* Parse pattern list to get the matching parameters */
2186 spec = (const struct rte_flow_item_tcp *)pattern->spec;
2187 last = (const struct rte_flow_item_tcp *)pattern->last;
2188 mask = (const struct rte_flow_item_tcp *)
2189 (pattern->mask ? pattern->mask : &dpaa2_flow_item_tcp_mask);
2191 /* Get traffic class index and flow id to be configured */
2192 flow->tc_id = group;
2193 flow->tc_index = attr->priority;
2195 if (!spec || !mc_l4_port_identification) {
2196 struct proto_discrimination proto;
2198 index = dpaa2_flow_extract_search(
2199 &priv->extract.qos_key_extract.dpkg,
2200 NET_PROT_IP, NH_FLD_IP_PROTO);
2202 ret = dpaa2_flow_proto_discrimination_extract(
2203 &priv->extract.qos_key_extract,
2204 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2207 "QoS Extract IP protocol to discriminate TCP failed.");
2211 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2214 index = dpaa2_flow_extract_search(
2215 &priv->extract.tc_key_extract[group].dpkg,
2216 NET_PROT_IP, NH_FLD_IP_PROTO);
2218 ret = dpaa2_flow_proto_discrimination_extract(
2219 &priv->extract.tc_key_extract[group],
2220 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2223 "FS Extract IP protocol to discriminate TCP failed.");
2227 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2230 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2233 "Move IP addr before TCP discrimination set failed");
2237 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2238 proto.ip_proto = IPPROTO_TCP;
2239 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2242 DPAA2_PMD_ERR("TCP discrimination rule set failed");
2246 (*device_configured) |= local_cfg;
2252 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2253 RTE_FLOW_ITEM_TYPE_TCP)) {
2254 DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
2259 if (mask->hdr.src_port) {
2260 index = dpaa2_flow_extract_search(
2261 &priv->extract.qos_key_extract.dpkg,
2262 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2264 ret = dpaa2_flow_extract_add(
2265 &priv->extract.qos_key_extract,
2267 NH_FLD_TCP_PORT_SRC,
2268 NH_FLD_TCP_PORT_SIZE);
2270 DPAA2_PMD_ERR("QoS Extract add TCP_SRC failed.");
2274 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2277 index = dpaa2_flow_extract_search(
2278 &priv->extract.tc_key_extract[group].dpkg,
2279 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2281 ret = dpaa2_flow_extract_add(
2282 &priv->extract.tc_key_extract[group],
2284 NH_FLD_TCP_PORT_SRC,
2285 NH_FLD_TCP_PORT_SIZE);
2287 DPAA2_PMD_ERR("FS Extract add TCP_SRC failed.");
2291 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2294 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2297 "Move ipaddr before TCP_PORT_SRC set failed");
2301 ret = dpaa2_flow_rule_data_set(
2302 &priv->extract.qos_key_extract,
2305 NH_FLD_TCP_PORT_SRC,
2306 &spec->hdr.src_port,
2307 &mask->hdr.src_port,
2308 NH_FLD_TCP_PORT_SIZE);
2311 "QoS NH_FLD_TCP_PORT_SRC rule data set failed");
2315 ret = dpaa2_flow_rule_data_set(
2316 &priv->extract.tc_key_extract[group],
2319 NH_FLD_TCP_PORT_SRC,
2320 &spec->hdr.src_port,
2321 &mask->hdr.src_port,
2322 NH_FLD_TCP_PORT_SIZE);
2325 "FS NH_FLD_TCP_PORT_SRC rule data set failed");
2330 if (mask->hdr.dst_port) {
2331 index = dpaa2_flow_extract_search(
2332 &priv->extract.qos_key_extract.dpkg,
2333 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2335 ret = dpaa2_flow_extract_add(
2336 &priv->extract.qos_key_extract,
2338 NH_FLD_TCP_PORT_DST,
2339 NH_FLD_TCP_PORT_SIZE);
2341 DPAA2_PMD_ERR("QoS Extract add TCP_DST failed.");
2345 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2348 index = dpaa2_flow_extract_search(
2349 &priv->extract.tc_key_extract[group].dpkg,
2350 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2352 ret = dpaa2_flow_extract_add(
2353 &priv->extract.tc_key_extract[group],
2355 NH_FLD_TCP_PORT_DST,
2356 NH_FLD_TCP_PORT_SIZE);
2358 DPAA2_PMD_ERR("FS Extract add TCP_DST failed.");
2362 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2365 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2368 "Move ipaddr before TCP_PORT_DST set failed");
2372 ret = dpaa2_flow_rule_data_set(
2373 &priv->extract.qos_key_extract,
2376 NH_FLD_TCP_PORT_DST,
2377 &spec->hdr.dst_port,
2378 &mask->hdr.dst_port,
2379 NH_FLD_TCP_PORT_SIZE);
2382 "QoS NH_FLD_TCP_PORT_DST rule data set failed");
2386 ret = dpaa2_flow_rule_data_set(
2387 &priv->extract.tc_key_extract[group],
2390 NH_FLD_TCP_PORT_DST,
2391 &spec->hdr.dst_port,
2392 &mask->hdr.dst_port,
2393 NH_FLD_TCP_PORT_SIZE);
2396 "FS NH_FLD_TCP_PORT_DST rule data set failed");
2401 (*device_configured) |= local_cfg;
2407 dpaa2_configure_flow_sctp(struct rte_flow *flow,
2408 struct rte_eth_dev *dev,
2409 const struct rte_flow_attr *attr,
2410 const struct rte_flow_item *pattern,
2411 const struct rte_flow_action actions[] __rte_unused,
2412 struct rte_flow_error *error __rte_unused,
2413 int *device_configured)
2418 const struct rte_flow_item_sctp *spec, *mask;
2420 const struct rte_flow_item_sctp *last __rte_unused;
2421 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2423 group = attr->group;
2425 /* Parse pattern list to get the matching parameters */
2426 spec = (const struct rte_flow_item_sctp *)pattern->spec;
2427 last = (const struct rte_flow_item_sctp *)pattern->last;
2428 mask = (const struct rte_flow_item_sctp *)
2429 (pattern->mask ? pattern->mask :
2430 &dpaa2_flow_item_sctp_mask);
2432 /* Get traffic class index and flow id to be configured */
2433 flow->tc_id = group;
2434 flow->tc_index = attr->priority;
2436 if (!spec || !mc_l4_port_identification) {
2437 struct proto_discrimination proto;
2439 index = dpaa2_flow_extract_search(
2440 &priv->extract.qos_key_extract.dpkg,
2441 NET_PROT_IP, NH_FLD_IP_PROTO);
2443 ret = dpaa2_flow_proto_discrimination_extract(
2444 &priv->extract.qos_key_extract,
2445 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2448 "QoS Extract IP protocol to discriminate SCTP failed.");
2452 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2455 index = dpaa2_flow_extract_search(
2456 &priv->extract.tc_key_extract[group].dpkg,
2457 NET_PROT_IP, NH_FLD_IP_PROTO);
2459 ret = dpaa2_flow_proto_discrimination_extract(
2460 &priv->extract.tc_key_extract[group],
2461 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2464 "FS Extract IP protocol to discriminate SCTP failed.");
2468 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2471 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2474 "Move ipaddr before SCTP discrimination set failed");
2478 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2479 proto.ip_proto = IPPROTO_SCTP;
2480 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2483 DPAA2_PMD_ERR("SCTP discrimination rule set failed");
2487 (*device_configured) |= local_cfg;
2493 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2494 RTE_FLOW_ITEM_TYPE_SCTP)) {
2495 DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
2500 if (mask->hdr.src_port) {
2501 index = dpaa2_flow_extract_search(
2502 &priv->extract.qos_key_extract.dpkg,
2503 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2505 ret = dpaa2_flow_extract_add(
2506 &priv->extract.qos_key_extract,
2508 NH_FLD_SCTP_PORT_SRC,
2509 NH_FLD_SCTP_PORT_SIZE);
2511 DPAA2_PMD_ERR("QoS Extract add SCTP_SRC failed.");
2515 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2518 index = dpaa2_flow_extract_search(
2519 &priv->extract.tc_key_extract[group].dpkg,
2520 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2522 ret = dpaa2_flow_extract_add(
2523 &priv->extract.tc_key_extract[group],
2525 NH_FLD_SCTP_PORT_SRC,
2526 NH_FLD_SCTP_PORT_SIZE);
2528 DPAA2_PMD_ERR("FS Extract add SCTP_SRC failed.");
2532 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2535 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2538 "Move ipaddr before SCTP_PORT_SRC set failed");
2542 ret = dpaa2_flow_rule_data_set(
2543 &priv->extract.qos_key_extract,
2546 NH_FLD_SCTP_PORT_SRC,
2547 &spec->hdr.src_port,
2548 &mask->hdr.src_port,
2549 NH_FLD_SCTP_PORT_SIZE);
2552 "QoS NH_FLD_SCTP_PORT_SRC rule data set failed");
2556 ret = dpaa2_flow_rule_data_set(
2557 &priv->extract.tc_key_extract[group],
2560 NH_FLD_SCTP_PORT_SRC,
2561 &spec->hdr.src_port,
2562 &mask->hdr.src_port,
2563 NH_FLD_SCTP_PORT_SIZE);
2566 "FS NH_FLD_SCTP_PORT_SRC rule data set failed");
2571 if (mask->hdr.dst_port) {
2572 index = dpaa2_flow_extract_search(
2573 &priv->extract.qos_key_extract.dpkg,
2574 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2576 ret = dpaa2_flow_extract_add(
2577 &priv->extract.qos_key_extract,
2579 NH_FLD_SCTP_PORT_DST,
2580 NH_FLD_SCTP_PORT_SIZE);
2582 DPAA2_PMD_ERR("QoS Extract add SCTP_DST failed.");
2586 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2589 index = dpaa2_flow_extract_search(
2590 &priv->extract.tc_key_extract[group].dpkg,
2591 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2593 ret = dpaa2_flow_extract_add(
2594 &priv->extract.tc_key_extract[group],
2596 NH_FLD_SCTP_PORT_DST,
2597 NH_FLD_SCTP_PORT_SIZE);
2599 DPAA2_PMD_ERR("FS Extract add SCTP_DST failed.");
2603 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2606 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2609 "Move ipaddr before SCTP_PORT_DST set failed");
2613 ret = dpaa2_flow_rule_data_set(
2614 &priv->extract.qos_key_extract,
2617 NH_FLD_SCTP_PORT_DST,
2618 &spec->hdr.dst_port,
2619 &mask->hdr.dst_port,
2620 NH_FLD_SCTP_PORT_SIZE);
2623 "QoS NH_FLD_SCTP_PORT_DST rule data set failed");
2627 ret = dpaa2_flow_rule_data_set(
2628 &priv->extract.tc_key_extract[group],
2631 NH_FLD_SCTP_PORT_DST,
2632 &spec->hdr.dst_port,
2633 &mask->hdr.dst_port,
2634 NH_FLD_SCTP_PORT_SIZE);
2637 "FS NH_FLD_SCTP_PORT_DST rule data set failed");
2642 (*device_configured) |= local_cfg;
2648 dpaa2_configure_flow_gre(struct rte_flow *flow,
2649 struct rte_eth_dev *dev,
2650 const struct rte_flow_attr *attr,
2651 const struct rte_flow_item *pattern,
2652 const struct rte_flow_action actions[] __rte_unused,
2653 struct rte_flow_error *error __rte_unused,
2654 int *device_configured)
2659 const struct rte_flow_item_gre *spec, *mask;
2661 const struct rte_flow_item_gre *last __rte_unused;
2662 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2664 group = attr->group;
2666 /* Parse pattern list to get the matching parameters */
2667 spec = (const struct rte_flow_item_gre *)pattern->spec;
2668 last = (const struct rte_flow_item_gre *)pattern->last;
2669 mask = (const struct rte_flow_item_gre *)
2670 (pattern->mask ? pattern->mask : &dpaa2_flow_item_gre_mask);
2672 /* Get traffic class index and flow id to be configured */
2673 flow->tc_id = group;
2674 flow->tc_index = attr->priority;
2677 struct proto_discrimination proto;
2679 index = dpaa2_flow_extract_search(
2680 &priv->extract.qos_key_extract.dpkg,
2681 NET_PROT_IP, NH_FLD_IP_PROTO);
2683 ret = dpaa2_flow_proto_discrimination_extract(
2684 &priv->extract.qos_key_extract,
2685 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2688 "QoS Extract IP protocol to discriminate GRE failed.");
2692 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2695 index = dpaa2_flow_extract_search(
2696 &priv->extract.tc_key_extract[group].dpkg,
2697 NET_PROT_IP, NH_FLD_IP_PROTO);
2699 ret = dpaa2_flow_proto_discrimination_extract(
2700 &priv->extract.tc_key_extract[group],
2701 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2704 "FS Extract IP protocol to discriminate GRE failed.");
2708 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2711 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2714 "Move IP addr before GRE discrimination set failed");
2718 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2719 proto.ip_proto = IPPROTO_GRE;
2720 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2723 DPAA2_PMD_ERR("GRE discrimination rule set failed");
2727 (*device_configured) |= local_cfg;
2732 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2733 RTE_FLOW_ITEM_TYPE_GRE)) {
2734 DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
2739 if (!mask->protocol)
2742 index = dpaa2_flow_extract_search(
2743 &priv->extract.qos_key_extract.dpkg,
2744 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2746 ret = dpaa2_flow_extract_add(
2747 &priv->extract.qos_key_extract,
2750 sizeof(rte_be16_t));
2752 DPAA2_PMD_ERR("QoS Extract add GRE_TYPE failed.");
2756 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2759 index = dpaa2_flow_extract_search(
2760 &priv->extract.tc_key_extract[group].dpkg,
2761 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2763 ret = dpaa2_flow_extract_add(
2764 &priv->extract.tc_key_extract[group],
2767 sizeof(rte_be16_t));
2769 DPAA2_PMD_ERR("FS Extract add GRE_TYPE failed.");
2773 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2776 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2779 "Move ipaddr before GRE_TYPE set failed");
2783 ret = dpaa2_flow_rule_data_set(
2784 &priv->extract.qos_key_extract,
2790 sizeof(rte_be16_t));
2793 "QoS NH_FLD_GRE_TYPE rule data set failed");
2797 ret = dpaa2_flow_rule_data_set(
2798 &priv->extract.tc_key_extract[group],
2804 sizeof(rte_be16_t));
2807 "FS NH_FLD_GRE_TYPE rule data set failed");
2811 (*device_configured) |= local_cfg;
2816 /* The existing QoS/FS entry with IP address(es)
2817 * needs update after
2818 * new extract(s) are inserted before IP
2819 * address(es) extract(s).
2822 dpaa2_flow_entry_update(
2823 struct dpaa2_dev_priv *priv, uint8_t tc_id)
2825 struct rte_flow *curr = LIST_FIRST(&priv->flows);
2826 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
2828 int qos_ipsrc_offset = -1, qos_ipdst_offset = -1;
2829 int fs_ipsrc_offset = -1, fs_ipdst_offset = -1;
2830 struct dpaa2_key_extract *qos_key_extract =
2831 &priv->extract.qos_key_extract;
2832 struct dpaa2_key_extract *tc_key_extract =
2833 &priv->extract.tc_key_extract[tc_id];
2834 char ipsrc_key[NH_FLD_IPV6_ADDR_SIZE];
2835 char ipdst_key[NH_FLD_IPV6_ADDR_SIZE];
2836 char ipsrc_mask[NH_FLD_IPV6_ADDR_SIZE];
2837 char ipdst_mask[NH_FLD_IPV6_ADDR_SIZE];
2838 int extend = -1, extend1, size = -1;
2842 if (curr->ipaddr_rule.ipaddr_type ==
2844 curr = LIST_NEXT(curr, next);
2848 if (curr->ipaddr_rule.ipaddr_type ==
2851 qos_key_extract->key_info.ipv4_src_offset;
2853 qos_key_extract->key_info.ipv4_dst_offset;
2855 tc_key_extract->key_info.ipv4_src_offset;
2857 tc_key_extract->key_info.ipv4_dst_offset;
2858 size = NH_FLD_IPV4_ADDR_SIZE;
2861 qos_key_extract->key_info.ipv6_src_offset;
2863 qos_key_extract->key_info.ipv6_dst_offset;
2865 tc_key_extract->key_info.ipv6_src_offset;
2867 tc_key_extract->key_info.ipv6_dst_offset;
2868 size = NH_FLD_IPV6_ADDR_SIZE;
2871 qos_index = curr->tc_id * priv->fs_entries +
2874 dpaa2_flow_qos_entry_log("Before update", curr, qos_index);
2876 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
2877 priv->token, &curr->qos_rule);
2879 DPAA2_PMD_ERR("Qos entry remove failed.");
2885 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2886 RTE_ASSERT(qos_ipsrc_offset >=
2887 curr->ipaddr_rule.qos_ipsrc_offset);
2888 extend1 = qos_ipsrc_offset -
2889 curr->ipaddr_rule.qos_ipsrc_offset;
2891 RTE_ASSERT(extend == extend1);
2895 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2896 (size == NH_FLD_IPV6_ADDR_SIZE));
2899 (char *)(size_t)curr->qos_rule.key_iova +
2900 curr->ipaddr_rule.qos_ipsrc_offset,
2902 memset((char *)(size_t)curr->qos_rule.key_iova +
2903 curr->ipaddr_rule.qos_ipsrc_offset,
2907 (char *)(size_t)curr->qos_rule.mask_iova +
2908 curr->ipaddr_rule.qos_ipsrc_offset,
2910 memset((char *)(size_t)curr->qos_rule.mask_iova +
2911 curr->ipaddr_rule.qos_ipsrc_offset,
2914 curr->ipaddr_rule.qos_ipsrc_offset = qos_ipsrc_offset;
2917 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2918 RTE_ASSERT(qos_ipdst_offset >=
2919 curr->ipaddr_rule.qos_ipdst_offset);
2920 extend1 = qos_ipdst_offset -
2921 curr->ipaddr_rule.qos_ipdst_offset;
2923 RTE_ASSERT(extend == extend1);
2927 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2928 (size == NH_FLD_IPV6_ADDR_SIZE));
2931 (char *)(size_t)curr->qos_rule.key_iova +
2932 curr->ipaddr_rule.qos_ipdst_offset,
2934 memset((char *)(size_t)curr->qos_rule.key_iova +
2935 curr->ipaddr_rule.qos_ipdst_offset,
2939 (char *)(size_t)curr->qos_rule.mask_iova +
2940 curr->ipaddr_rule.qos_ipdst_offset,
2942 memset((char *)(size_t)curr->qos_rule.mask_iova +
2943 curr->ipaddr_rule.qos_ipdst_offset,
2946 curr->ipaddr_rule.qos_ipdst_offset = qos_ipdst_offset;
2949 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2950 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2951 (size == NH_FLD_IPV6_ADDR_SIZE));
2952 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2953 curr->ipaddr_rule.qos_ipsrc_offset,
2956 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2957 curr->ipaddr_rule.qos_ipsrc_offset,
2961 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2962 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2963 (size == NH_FLD_IPV6_ADDR_SIZE));
2964 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2965 curr->ipaddr_rule.qos_ipdst_offset,
2968 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2969 curr->ipaddr_rule.qos_ipdst_offset,
2975 curr->qos_real_key_size += extend;
2977 curr->qos_rule.key_size = FIXED_ENTRY_SIZE;
2979 dpaa2_flow_qos_entry_log("Start update", curr, qos_index);
2981 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
2982 priv->token, &curr->qos_rule,
2983 curr->tc_id, qos_index,
2986 DPAA2_PMD_ERR("Qos entry update failed.");
2990 if (curr->action != RTE_FLOW_ACTION_TYPE_QUEUE) {
2991 curr = LIST_NEXT(curr, next);
2995 dpaa2_flow_fs_entry_log("Before update", curr);
2998 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW,
2999 priv->token, curr->tc_id, &curr->fs_rule);
3001 DPAA2_PMD_ERR("FS entry remove failed.");
3005 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0 &&
3006 tc_id == curr->tc_id) {
3007 RTE_ASSERT(fs_ipsrc_offset >=
3008 curr->ipaddr_rule.fs_ipsrc_offset);
3009 extend1 = fs_ipsrc_offset -
3010 curr->ipaddr_rule.fs_ipsrc_offset;
3012 RTE_ASSERT(extend == extend1);
3017 (char *)(size_t)curr->fs_rule.key_iova +
3018 curr->ipaddr_rule.fs_ipsrc_offset,
3020 memset((char *)(size_t)curr->fs_rule.key_iova +
3021 curr->ipaddr_rule.fs_ipsrc_offset,
3025 (char *)(size_t)curr->fs_rule.mask_iova +
3026 curr->ipaddr_rule.fs_ipsrc_offset,
3028 memset((char *)(size_t)curr->fs_rule.mask_iova +
3029 curr->ipaddr_rule.fs_ipsrc_offset,
3032 curr->ipaddr_rule.fs_ipsrc_offset = fs_ipsrc_offset;
3035 if (curr->ipaddr_rule.fs_ipdst_offset >= 0 &&
3036 tc_id == curr->tc_id) {
3037 RTE_ASSERT(fs_ipdst_offset >=
3038 curr->ipaddr_rule.fs_ipdst_offset);
3039 extend1 = fs_ipdst_offset -
3040 curr->ipaddr_rule.fs_ipdst_offset;
3042 RTE_ASSERT(extend == extend1);
3047 (char *)(size_t)curr->fs_rule.key_iova +
3048 curr->ipaddr_rule.fs_ipdst_offset,
3050 memset((char *)(size_t)curr->fs_rule.key_iova +
3051 curr->ipaddr_rule.fs_ipdst_offset,
3055 (char *)(size_t)curr->fs_rule.mask_iova +
3056 curr->ipaddr_rule.fs_ipdst_offset,
3058 memset((char *)(size_t)curr->fs_rule.mask_iova +
3059 curr->ipaddr_rule.fs_ipdst_offset,
3062 curr->ipaddr_rule.fs_ipdst_offset = fs_ipdst_offset;
3065 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0) {
3066 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3067 curr->ipaddr_rule.fs_ipsrc_offset,
3070 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3071 curr->ipaddr_rule.fs_ipsrc_offset,
3075 if (curr->ipaddr_rule.fs_ipdst_offset >= 0) {
3076 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3077 curr->ipaddr_rule.fs_ipdst_offset,
3080 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3081 curr->ipaddr_rule.fs_ipdst_offset,
3087 curr->fs_real_key_size += extend;
3088 curr->fs_rule.key_size = FIXED_ENTRY_SIZE;
3090 dpaa2_flow_fs_entry_log("Start update", curr);
3092 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
3093 priv->token, curr->tc_id, curr->tc_index,
3094 &curr->fs_rule, &curr->action_cfg);
3096 DPAA2_PMD_ERR("FS entry update failed.");
3100 curr = LIST_NEXT(curr, next);
3107 dpaa2_flow_verify_attr(
3108 struct dpaa2_dev_priv *priv,
3109 const struct rte_flow_attr *attr)
3111 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3114 if (curr->tc_id == attr->group &&
3115 curr->tc_index == attr->priority) {
3117 "Flow with group %d and priority %d already exists.",
3118 attr->group, attr->priority);
3122 curr = LIST_NEXT(curr, next);
3129 dpaa2_generic_flow_set(struct rte_flow *flow,
3130 struct rte_eth_dev *dev,
3131 const struct rte_flow_attr *attr,
3132 const struct rte_flow_item pattern[],
3133 const struct rte_flow_action actions[],
3134 struct rte_flow_error *error)
3136 const struct rte_flow_action_queue *dest_queue;
3137 const struct rte_flow_action_rss *rss_conf;
3138 int is_keycfg_configured = 0, end_of_list = 0;
3139 int ret = 0, i = 0, j = 0;
3140 struct dpni_rx_tc_dist_cfg tc_cfg;
3141 struct dpni_qos_tbl_cfg qos_cfg;
3142 struct dpni_fs_action_cfg action;
3143 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3144 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3146 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3149 ret = dpaa2_flow_verify_attr(priv, attr);
3153 /* Parse pattern list to get the matching parameters */
3154 while (!end_of_list) {
3155 switch (pattern[i].type) {
3156 case RTE_FLOW_ITEM_TYPE_ETH:
3157 ret = dpaa2_configure_flow_eth(flow,
3158 dev, attr, &pattern[i], actions, error,
3159 &is_keycfg_configured);
3161 DPAA2_PMD_ERR("ETH flow configuration failed!");
3165 case RTE_FLOW_ITEM_TYPE_VLAN:
3166 ret = dpaa2_configure_flow_vlan(flow,
3167 dev, attr, &pattern[i], actions, error,
3168 &is_keycfg_configured);
3170 DPAA2_PMD_ERR("vLan flow configuration failed!");
3174 case RTE_FLOW_ITEM_TYPE_IPV4:
3175 case RTE_FLOW_ITEM_TYPE_IPV6:
3176 ret = dpaa2_configure_flow_generic_ip(flow,
3177 dev, attr, &pattern[i], actions, error,
3178 &is_keycfg_configured);
3180 DPAA2_PMD_ERR("IP flow configuration failed!");
3184 case RTE_FLOW_ITEM_TYPE_ICMP:
3185 ret = dpaa2_configure_flow_icmp(flow,
3186 dev, attr, &pattern[i], actions, error,
3187 &is_keycfg_configured);
3189 DPAA2_PMD_ERR("ICMP flow configuration failed!");
3193 case RTE_FLOW_ITEM_TYPE_UDP:
3194 ret = dpaa2_configure_flow_udp(flow,
3195 dev, attr, &pattern[i], actions, error,
3196 &is_keycfg_configured);
3198 DPAA2_PMD_ERR("UDP flow configuration failed!");
3202 case RTE_FLOW_ITEM_TYPE_TCP:
3203 ret = dpaa2_configure_flow_tcp(flow,
3204 dev, attr, &pattern[i], actions, error,
3205 &is_keycfg_configured);
3207 DPAA2_PMD_ERR("TCP flow configuration failed!");
3211 case RTE_FLOW_ITEM_TYPE_SCTP:
3212 ret = dpaa2_configure_flow_sctp(flow,
3213 dev, attr, &pattern[i], actions, error,
3214 &is_keycfg_configured);
3216 DPAA2_PMD_ERR("SCTP flow configuration failed!");
3220 case RTE_FLOW_ITEM_TYPE_GRE:
3221 ret = dpaa2_configure_flow_gre(flow,
3222 dev, attr, &pattern[i], actions, error,
3223 &is_keycfg_configured);
3225 DPAA2_PMD_ERR("GRE flow configuration failed!");
3229 case RTE_FLOW_ITEM_TYPE_END:
3231 break; /*End of List*/
3233 DPAA2_PMD_ERR("Invalid action type");
3240 /* Let's parse action on matching traffic */
3242 while (!end_of_list) {
3243 switch (actions[j].type) {
3244 case RTE_FLOW_ACTION_TYPE_QUEUE:
3246 (const struct rte_flow_action_queue *)(actions[j].conf);
3247 flow->flow_id = dest_queue->index;
3248 flow->action = RTE_FLOW_ACTION_TYPE_QUEUE;
3249 memset(&action, 0, sizeof(struct dpni_fs_action_cfg));
3250 action.flow_id = flow->flow_id;
3251 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3252 dpaa2_flow_qos_table_extracts_log(priv);
3253 if (dpkg_prepare_key_cfg(
3254 &priv->extract.qos_key_extract.dpkg,
3255 (uint8_t *)(size_t)priv->extract.qos_extract_param)
3258 "Unable to prepare extract parameters");
3262 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
3263 qos_cfg.discard_on_miss = true;
3264 qos_cfg.keep_entries = true;
3265 qos_cfg.key_cfg_iova =
3266 (size_t)priv->extract.qos_extract_param;
3267 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3268 priv->token, &qos_cfg);
3271 "Distribution cannot be configured.(%d)"
3276 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
3277 dpaa2_flow_fs_table_extracts_log(priv, flow->tc_id);
3278 if (dpkg_prepare_key_cfg(
3279 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3280 (uint8_t *)(size_t)priv->extract
3281 .tc_extract_param[flow->tc_id]) < 0) {
3283 "Unable to prepare extract parameters");
3287 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3288 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc;
3289 tc_cfg.dist_mode = DPNI_DIST_MODE_FS;
3290 tc_cfg.key_cfg_iova =
3291 (uint64_t)priv->extract.tc_extract_param[flow->tc_id];
3292 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3293 tc_cfg.fs_cfg.keep_entries = true;
3294 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3296 flow->tc_id, &tc_cfg);
3299 "Distribution cannot be configured.(%d)"
3304 /* Configure QoS table first */
3306 action.flow_id = action.flow_id % priv->num_rx_tc;
3308 qos_index = flow->tc_id * priv->fs_entries +
3311 if (qos_index >= priv->qos_entries) {
3312 DPAA2_PMD_ERR("QoS table with %d entries full",
3316 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3317 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR) {
3318 if (flow->ipaddr_rule.qos_ipdst_offset >=
3319 flow->ipaddr_rule.qos_ipsrc_offset) {
3320 flow->qos_real_key_size =
3321 flow->ipaddr_rule.qos_ipdst_offset +
3322 NH_FLD_IPV4_ADDR_SIZE;
3324 flow->qos_real_key_size =
3325 flow->ipaddr_rule.qos_ipsrc_offset +
3326 NH_FLD_IPV4_ADDR_SIZE;
3328 } else if (flow->ipaddr_rule.ipaddr_type ==
3330 if (flow->ipaddr_rule.qos_ipdst_offset >=
3331 flow->ipaddr_rule.qos_ipsrc_offset) {
3332 flow->qos_real_key_size =
3333 flow->ipaddr_rule.qos_ipdst_offset +
3334 NH_FLD_IPV6_ADDR_SIZE;
3336 flow->qos_real_key_size =
3337 flow->ipaddr_rule.qos_ipsrc_offset +
3338 NH_FLD_IPV6_ADDR_SIZE;
3342 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3344 dpaa2_flow_qos_entry_log("Start add", flow, qos_index);
3346 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
3347 priv->token, &flow->qos_rule,
3348 flow->tc_id, qos_index,
3352 "Error in addnig entry to QoS table(%d)", ret);
3356 /* Then Configure FS table */
3357 if (flow->tc_index >= priv->fs_entries) {
3358 DPAA2_PMD_ERR("FS table with %d entries full",
3363 flow->fs_real_key_size =
3364 priv->extract.tc_key_extract[flow->tc_id]
3365 .key_info.key_total_size;
3367 if (flow->ipaddr_rule.ipaddr_type ==
3369 if (flow->ipaddr_rule.fs_ipdst_offset >=
3370 flow->ipaddr_rule.fs_ipsrc_offset) {
3371 flow->fs_real_key_size =
3372 flow->ipaddr_rule.fs_ipdst_offset +
3373 NH_FLD_IPV4_ADDR_SIZE;
3375 flow->fs_real_key_size =
3376 flow->ipaddr_rule.fs_ipsrc_offset +
3377 NH_FLD_IPV4_ADDR_SIZE;
3379 } else if (flow->ipaddr_rule.ipaddr_type ==
3381 if (flow->ipaddr_rule.fs_ipdst_offset >=
3382 flow->ipaddr_rule.fs_ipsrc_offset) {
3383 flow->fs_real_key_size =
3384 flow->ipaddr_rule.fs_ipdst_offset +
3385 NH_FLD_IPV6_ADDR_SIZE;
3387 flow->fs_real_key_size =
3388 flow->ipaddr_rule.fs_ipsrc_offset +
3389 NH_FLD_IPV6_ADDR_SIZE;
3393 flow->fs_rule.key_size = FIXED_ENTRY_SIZE;
3395 dpaa2_flow_fs_entry_log("Start add", flow);
3397 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3398 flow->tc_id, flow->tc_index,
3399 &flow->fs_rule, &action);
3402 "Error in adding entry to FS table(%d)", ret);
3405 memcpy(&flow->action_cfg, &action,
3406 sizeof(struct dpni_fs_action_cfg));
3408 case RTE_FLOW_ACTION_TYPE_RSS:
3409 rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf);
3410 for (i = 0; i < (int)rss_conf->queue_num; i++) {
3411 if (rss_conf->queue[i] <
3412 (attr->group * priv->dist_queues) ||
3413 rss_conf->queue[i] >=
3414 ((attr->group + 1) * priv->dist_queues)) {
3416 "Queue/Group combination are not supported\n");
3421 flow->action = RTE_FLOW_ACTION_TYPE_RSS;
3422 ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
3423 &priv->extract.tc_key_extract[flow->tc_id].dpkg);
3426 "unable to set flow distribution.please check queue config\n");
3430 /* Allocate DMA'ble memory to write the rules */
3431 param = (size_t)rte_malloc(NULL, 256, 64);
3433 DPAA2_PMD_ERR("Memory allocation failure\n");
3437 if (dpkg_prepare_key_cfg(
3438 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3439 (uint8_t *)param) < 0) {
3441 "Unable to prepare extract parameters");
3442 rte_free((void *)param);
3446 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3447 tc_cfg.dist_size = rss_conf->queue_num;
3448 tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
3449 tc_cfg.key_cfg_iova = (size_t)param;
3450 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3452 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3453 priv->token, flow->tc_id,
3457 "Distribution cannot be configured: %d\n", ret);
3458 rte_free((void *)param);
3462 rte_free((void *)param);
3463 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3464 if (dpkg_prepare_key_cfg(
3465 &priv->extract.qos_key_extract.dpkg,
3466 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3468 "Unable to prepare extract parameters");
3472 sizeof(struct dpni_qos_tbl_cfg));
3473 qos_cfg.discard_on_miss = true;
3474 qos_cfg.keep_entries = true;
3475 qos_cfg.key_cfg_iova =
3476 (size_t)priv->extract.qos_extract_param;
3477 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3478 priv->token, &qos_cfg);
3481 "Distribution can't be configured %d\n",
3487 /* Add Rule into QoS table */
3488 qos_index = flow->tc_id * priv->fs_entries +
3490 if (qos_index >= priv->qos_entries) {
3491 DPAA2_PMD_ERR("QoS table with %d entries full",
3496 flow->qos_real_key_size =
3497 priv->extract.qos_key_extract.key_info.key_total_size;
3498 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3499 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3500 &flow->qos_rule, flow->tc_id,
3504 "Error in entry addition in QoS table(%d)",
3509 case RTE_FLOW_ACTION_TYPE_END:
3513 DPAA2_PMD_ERR("Invalid action type");
3521 if (is_keycfg_configured &
3522 (DPAA2_QOS_TABLE_RECONFIGURE |
3523 DPAA2_FS_TABLE_RECONFIGURE)) {
3524 ret = dpaa2_flow_entry_update(priv, flow->tc_id);
3526 DPAA2_PMD_ERR("Flow entry update failed.");
3531 /* New rules are inserted. */
3533 LIST_INSERT_HEAD(&priv->flows, flow, next);
3535 while (LIST_NEXT(curr, next))
3536 curr = LIST_NEXT(curr, next);
3537 LIST_INSERT_AFTER(curr, flow, next);
3544 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
3545 const struct rte_flow_attr *attr)
3549 if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
3550 DPAA2_PMD_ERR("Priority group is out of range\n");
3553 if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
3554 DPAA2_PMD_ERR("Priority within the group is out of range\n");
3557 if (unlikely(attr->egress)) {
3559 "Flow configuration is not supported on egress side\n");
3562 if (unlikely(!attr->ingress)) {
3563 DPAA2_PMD_ERR("Ingress flag must be configured\n");
3570 dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
3572 unsigned int i, j, is_found = 0;
3575 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3576 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) {
3577 if (dpaa2_supported_pattern_type[i]
3578 == pattern[j].type) {
3588 /* Lets verify other combinations of given pattern rules */
3589 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3590 if (!pattern[j].spec) {
3600 dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
3602 unsigned int i, j, is_found = 0;
3605 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3606 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
3607 if (dpaa2_supported_action_type[i] == actions[j].type) {
3617 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3618 if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
3626 int dpaa2_flow_validate(struct rte_eth_dev *dev,
3627 const struct rte_flow_attr *flow_attr,
3628 const struct rte_flow_item pattern[],
3629 const struct rte_flow_action actions[],
3630 struct rte_flow_error *error)
3632 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3633 struct dpni_attr dpni_attr;
3634 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3635 uint16_t token = priv->token;
3638 memset(&dpni_attr, 0, sizeof(struct dpni_attr));
3639 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
3642 "Failure to get dpni@%p attribute, err code %d\n",
3644 rte_flow_error_set(error, EPERM,
3645 RTE_FLOW_ERROR_TYPE_ATTR,
3646 flow_attr, "invalid");
3650 /* Verify input attributes */
3651 ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
3654 "Invalid attributes are given\n");
3655 rte_flow_error_set(error, EPERM,
3656 RTE_FLOW_ERROR_TYPE_ATTR,
3657 flow_attr, "invalid");
3658 goto not_valid_params;
3660 /* Verify input pattern list */
3661 ret = dpaa2_dev_verify_patterns(pattern);
3664 "Invalid pattern list is given\n");
3665 rte_flow_error_set(error, EPERM,
3666 RTE_FLOW_ERROR_TYPE_ITEM,
3667 pattern, "invalid");
3668 goto not_valid_params;
3670 /* Verify input action list */
3671 ret = dpaa2_dev_verify_actions(actions);
3674 "Invalid action list is given\n");
3675 rte_flow_error_set(error, EPERM,
3676 RTE_FLOW_ERROR_TYPE_ACTION,
3677 actions, "invalid");
3678 goto not_valid_params;
3685 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev,
3686 const struct rte_flow_attr *attr,
3687 const struct rte_flow_item pattern[],
3688 const struct rte_flow_action actions[],
3689 struct rte_flow_error *error)
3691 struct rte_flow *flow = NULL;
3692 size_t key_iova = 0, mask_iova = 0;
3695 dpaa2_flow_control_log =
3696 getenv("DPAA2_FLOW_CONTROL_LOG");
3698 flow = rte_zmalloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE);
3700 DPAA2_PMD_ERR("Failure to allocate memory for flow");
3703 /* Allocate DMA'ble memory to write the rules */
3704 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3707 "Memory allocation failure for rule configuration\n");
3710 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3713 "Memory allocation failure for rule configuration\n");
3717 flow->qos_rule.key_iova = key_iova;
3718 flow->qos_rule.mask_iova = mask_iova;
3720 /* Allocate DMA'ble memory to write the rules */
3721 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3724 "Memory allocation failure for rule configuration\n");
3727 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3730 "Memory allocation failure for rule configuration\n");
3734 flow->fs_rule.key_iova = key_iova;
3735 flow->fs_rule.mask_iova = mask_iova;
3737 flow->ipaddr_rule.ipaddr_type = FLOW_NONE_IPADDR;
3738 flow->ipaddr_rule.qos_ipsrc_offset =
3739 IP_ADDRESS_OFFSET_INVALID;
3740 flow->ipaddr_rule.qos_ipdst_offset =
3741 IP_ADDRESS_OFFSET_INVALID;
3742 flow->ipaddr_rule.fs_ipsrc_offset =
3743 IP_ADDRESS_OFFSET_INVALID;
3744 flow->ipaddr_rule.fs_ipdst_offset =
3745 IP_ADDRESS_OFFSET_INVALID;
3747 switch (dpaa2_filter_type) {
3748 case RTE_ETH_FILTER_GENERIC:
3749 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern,
3752 if (error->type > RTE_FLOW_ERROR_TYPE_ACTION)
3753 rte_flow_error_set(error, EPERM,
3754 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3757 "Failure to create flow, return code (%d)", ret);
3758 goto creation_error;
3762 DPAA2_PMD_ERR("Filter type (%d) not supported",
3769 rte_flow_error_set(error, EPERM,
3770 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3771 NULL, "memory alloc");
3773 rte_free((void *)flow);
3774 rte_free((void *)key_iova);
3775 rte_free((void *)mask_iova);
3781 int dpaa2_flow_destroy(struct rte_eth_dev *dev,
3782 struct rte_flow *flow,
3783 struct rte_flow_error *error)
3786 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3787 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3789 switch (flow->action) {
3790 case RTE_FLOW_ACTION_TYPE_QUEUE:
3791 /* Remove entry from QoS table first */
3792 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3796 "Error in adding entry to QoS table(%d)", ret);
3800 /* Then remove entry from FS table */
3801 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3802 flow->tc_id, &flow->fs_rule);
3805 "Error in entry addition in FS table(%d)", ret);
3809 case RTE_FLOW_ACTION_TYPE_RSS:
3810 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3814 "Error in entry addition in QoS table(%d)", ret);
3820 "Action type (%d) is not supported", flow->action);
3825 LIST_REMOVE(flow, next);
3826 rte_free((void *)(size_t)flow->qos_rule.key_iova);
3827 rte_free((void *)(size_t)flow->qos_rule.mask_iova);
3828 rte_free((void *)(size_t)flow->fs_rule.key_iova);
3829 rte_free((void *)(size_t)flow->fs_rule.mask_iova);
3830 /* Now free the flow */
3835 rte_flow_error_set(error, EPERM,
3836 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3842 * Destroy user-configured flow rules.
3844 * This function skips internal flows rules.
3846 * @see rte_flow_flush()
3850 dpaa2_flow_flush(struct rte_eth_dev *dev,
3851 struct rte_flow_error *error)
3853 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3854 struct rte_flow *flow = LIST_FIRST(&priv->flows);
3857 struct rte_flow *next = LIST_NEXT(flow, next);
3859 dpaa2_flow_destroy(dev, flow, error);
3866 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
3867 struct rte_flow *flow __rte_unused,
3868 const struct rte_flow_action *actions __rte_unused,
3869 void *data __rte_unused,
3870 struct rte_flow_error *error __rte_unused)
3876 * Clean up all flow rules.
3878 * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
3879 * rules regardless of whether they are internal or user-configured.
3882 * Pointer to private structure.
3885 dpaa2_flow_clean(struct rte_eth_dev *dev)
3887 struct rte_flow *flow;
3888 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3890 while ((flow = LIST_FIRST(&priv->flows)))
3891 dpaa2_flow_destroy(dev, flow, NULL);
3894 const struct rte_flow_ops dpaa2_flow_ops = {
3895 .create = dpaa2_flow_create,
3896 .validate = dpaa2_flow_validate,
3897 .destroy = dpaa2_flow_destroy,
3898 .flush = dpaa2_flow_flush,
3899 .query = dpaa2_flow_query,