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;
59 /* Special for IP address to specify the offset
62 struct flow_rule_ipaddr ipaddr_rule;
63 struct dpni_fs_action_cfg action_cfg;
67 enum rte_flow_item_type dpaa2_supported_pattern_type[] = {
68 RTE_FLOW_ITEM_TYPE_END,
69 RTE_FLOW_ITEM_TYPE_ETH,
70 RTE_FLOW_ITEM_TYPE_VLAN,
71 RTE_FLOW_ITEM_TYPE_IPV4,
72 RTE_FLOW_ITEM_TYPE_IPV6,
73 RTE_FLOW_ITEM_TYPE_ICMP,
74 RTE_FLOW_ITEM_TYPE_UDP,
75 RTE_FLOW_ITEM_TYPE_TCP,
76 RTE_FLOW_ITEM_TYPE_SCTP,
77 RTE_FLOW_ITEM_TYPE_GRE,
81 enum rte_flow_action_type dpaa2_supported_action_type[] = {
82 RTE_FLOW_ACTION_TYPE_END,
83 RTE_FLOW_ACTION_TYPE_QUEUE,
84 RTE_FLOW_ACTION_TYPE_RSS
87 /* Max of enum rte_flow_item_type + 1, for both IPv4 and IPv6*/
88 #define DPAA2_FLOW_ITEM_TYPE_GENERIC_IP (RTE_FLOW_ITEM_TYPE_META + 1)
90 enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE;
93 static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = {
94 .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
95 .src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
96 .type = RTE_BE16(0xffff),
99 static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = {
100 .tci = RTE_BE16(0xffff),
103 static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = {
104 .hdr.src_addr = RTE_BE32(0xffffffff),
105 .hdr.dst_addr = RTE_BE32(0xffffffff),
106 .hdr.next_proto_id = 0xff,
109 static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = {
112 "\xff\xff\xff\xff\xff\xff\xff\xff"
113 "\xff\xff\xff\xff\xff\xff\xff\xff",
115 "\xff\xff\xff\xff\xff\xff\xff\xff"
116 "\xff\xff\xff\xff\xff\xff\xff\xff",
121 static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = {
122 .hdr.icmp_type = 0xff,
123 .hdr.icmp_code = 0xff,
126 static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = {
128 .src_port = RTE_BE16(0xffff),
129 .dst_port = RTE_BE16(0xffff),
133 static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = {
135 .src_port = RTE_BE16(0xffff),
136 .dst_port = RTE_BE16(0xffff),
140 static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = {
142 .src_port = RTE_BE16(0xffff),
143 .dst_port = RTE_BE16(0xffff),
147 static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = {
148 .protocol = RTE_BE16(0xffff),
153 static inline void dpaa2_prot_field_string(
154 enum net_prot prot, uint32_t field,
157 if (!dpaa2_flow_control_log)
160 if (prot == NET_PROT_ETH) {
161 strcpy(string, "eth");
162 if (field == NH_FLD_ETH_DA)
163 strcat(string, ".dst");
164 else if (field == NH_FLD_ETH_SA)
165 strcat(string, ".src");
166 else if (field == NH_FLD_ETH_TYPE)
167 strcat(string, ".type");
169 strcat(string, ".unknown field");
170 } else if (prot == NET_PROT_VLAN) {
171 strcpy(string, "vlan");
172 if (field == NH_FLD_VLAN_TCI)
173 strcat(string, ".tci");
175 strcat(string, ".unknown field");
176 } else if (prot == NET_PROT_IP) {
177 strcpy(string, "ip");
178 if (field == NH_FLD_IP_SRC)
179 strcat(string, ".src");
180 else if (field == NH_FLD_IP_DST)
181 strcat(string, ".dst");
182 else if (field == NH_FLD_IP_PROTO)
183 strcat(string, ".proto");
185 strcat(string, ".unknown field");
186 } else if (prot == NET_PROT_TCP) {
187 strcpy(string, "tcp");
188 if (field == NH_FLD_TCP_PORT_SRC)
189 strcat(string, ".src");
190 else if (field == NH_FLD_TCP_PORT_DST)
191 strcat(string, ".dst");
193 strcat(string, ".unknown field");
194 } else if (prot == NET_PROT_UDP) {
195 strcpy(string, "udp");
196 if (field == NH_FLD_UDP_PORT_SRC)
197 strcat(string, ".src");
198 else if (field == NH_FLD_UDP_PORT_DST)
199 strcat(string, ".dst");
201 strcat(string, ".unknown field");
202 } else if (prot == NET_PROT_ICMP) {
203 strcpy(string, "icmp");
204 if (field == NH_FLD_ICMP_TYPE)
205 strcat(string, ".type");
206 else if (field == NH_FLD_ICMP_CODE)
207 strcat(string, ".code");
209 strcat(string, ".unknown field");
210 } else if (prot == NET_PROT_SCTP) {
211 strcpy(string, "sctp");
212 if (field == NH_FLD_SCTP_PORT_SRC)
213 strcat(string, ".src");
214 else if (field == NH_FLD_SCTP_PORT_DST)
215 strcat(string, ".dst");
217 strcat(string, ".unknown field");
218 } else if (prot == NET_PROT_GRE) {
219 strcpy(string, "gre");
220 if (field == NH_FLD_GRE_TYPE)
221 strcat(string, ".type");
223 strcat(string, ".unknown field");
225 strcpy(string, "unknown protocol");
229 static inline void dpaa2_flow_qos_table_extracts_log(
230 const struct dpaa2_dev_priv *priv)
235 if (!dpaa2_flow_control_log)
238 printf("Setup QoS table: number of extracts: %d\r\n",
239 priv->extract.qos_key_extract.dpkg.num_extracts);
240 for (idx = 0; idx < priv->extract.qos_key_extract.dpkg.num_extracts;
242 dpaa2_prot_field_string(priv->extract.qos_key_extract.dpkg
243 .extracts[idx].extract.from_hdr.prot,
244 priv->extract.qos_key_extract.dpkg.extracts[idx]
245 .extract.from_hdr.field,
247 printf("%s", string);
248 if ((idx + 1) < priv->extract.qos_key_extract.dpkg.num_extracts)
254 static inline void dpaa2_flow_fs_table_extracts_log(
255 const struct dpaa2_dev_priv *priv, int tc_id)
260 if (!dpaa2_flow_control_log)
263 printf("Setup FS table: number of extracts of TC[%d]: %d\r\n",
264 tc_id, priv->extract.tc_key_extract[tc_id]
266 for (idx = 0; idx < priv->extract.tc_key_extract[tc_id]
267 .dpkg.num_extracts; idx++) {
268 dpaa2_prot_field_string(priv->extract.tc_key_extract[tc_id]
269 .dpkg.extracts[idx].extract.from_hdr.prot,
270 priv->extract.tc_key_extract[tc_id].dpkg.extracts[idx]
271 .extract.from_hdr.field,
273 printf("%s", string);
274 if ((idx + 1) < priv->extract.tc_key_extract[tc_id]
281 static inline void dpaa2_flow_qos_entry_log(
282 const char *log_info, const struct rte_flow *flow, int qos_index)
287 if (!dpaa2_flow_control_log)
290 printf("\r\n%s QoS entry[%d] for TC[%d], extracts size is %d\r\n",
291 log_info, qos_index, flow->tc_id, flow->qos_real_key_size);
293 key = (uint8_t *)(size_t)flow->qos_rule.key_iova;
294 mask = (uint8_t *)(size_t)flow->qos_rule.mask_iova;
297 for (idx = 0; idx < flow->qos_real_key_size; idx++)
298 printf("%02x ", key[idx]);
300 printf("\r\nmask:\r\n");
301 for (idx = 0; idx < flow->qos_real_key_size; idx++)
302 printf("%02x ", mask[idx]);
304 printf("\r\n%s QoS ipsrc: %d, ipdst: %d\r\n", log_info,
305 flow->ipaddr_rule.qos_ipsrc_offset,
306 flow->ipaddr_rule.qos_ipdst_offset);
309 static inline void dpaa2_flow_fs_entry_log(
310 const char *log_info, const struct rte_flow *flow)
315 if (!dpaa2_flow_control_log)
318 printf("\r\n%s FS/TC entry[%d] of TC[%d], extracts size is %d\r\n",
319 log_info, flow->tc_index, flow->tc_id, flow->fs_real_key_size);
321 key = (uint8_t *)(size_t)flow->fs_rule.key_iova;
322 mask = (uint8_t *)(size_t)flow->fs_rule.mask_iova;
325 for (idx = 0; idx < flow->fs_real_key_size; idx++)
326 printf("%02x ", key[idx]);
328 printf("\r\nmask:\r\n");
329 for (idx = 0; idx < flow->fs_real_key_size; idx++)
330 printf("%02x ", mask[idx]);
332 printf("\r\n%s FS ipsrc: %d, ipdst: %d\r\n", log_info,
333 flow->ipaddr_rule.fs_ipsrc_offset,
334 flow->ipaddr_rule.fs_ipdst_offset);
337 static inline void dpaa2_flow_extract_key_set(
338 struct dpaa2_key_info *key_info, int index, uint8_t size)
340 key_info->key_size[index] = size;
342 key_info->key_offset[index] =
343 key_info->key_offset[index - 1] +
344 key_info->key_size[index - 1];
346 key_info->key_offset[index] = 0;
348 key_info->key_total_size += size;
351 static int dpaa2_flow_extract_add(
352 struct dpaa2_key_extract *key_extract,
354 uint32_t field, uint8_t field_size)
356 int index, ip_src = -1, ip_dst = -1;
357 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
358 struct dpaa2_key_info *key_info = &key_extract->key_info;
360 if (dpkg->num_extracts >=
361 DPKG_MAX_NUM_OF_EXTRACTS) {
362 DPAA2_PMD_WARN("Number of extracts overflows");
365 /* Before reorder, the IP SRC and IP DST are already last
368 for (index = 0; index < dpkg->num_extracts; index++) {
369 if (dpkg->extracts[index].extract.from_hdr.prot ==
371 if (dpkg->extracts[index].extract.from_hdr.field ==
375 if (dpkg->extracts[index].extract.from_hdr.field ==
383 RTE_ASSERT((ip_src + 2) >= dpkg->num_extracts);
386 RTE_ASSERT((ip_dst + 2) >= dpkg->num_extracts);
388 if (prot == NET_PROT_IP &&
389 (field == NH_FLD_IP_SRC ||
390 field == NH_FLD_IP_DST)) {
391 index = dpkg->num_extracts;
393 if (ip_src >= 0 && ip_dst >= 0)
394 index = dpkg->num_extracts - 2;
395 else if (ip_src >= 0 || ip_dst >= 0)
396 index = dpkg->num_extracts - 1;
398 index = dpkg->num_extracts;
401 dpkg->extracts[index].type = DPKG_EXTRACT_FROM_HDR;
402 dpkg->extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
403 dpkg->extracts[index].extract.from_hdr.prot = prot;
404 dpkg->extracts[index].extract.from_hdr.field = field;
405 if (prot == NET_PROT_IP &&
406 (field == NH_FLD_IP_SRC ||
407 field == NH_FLD_IP_DST)) {
408 dpaa2_flow_extract_key_set(key_info, index, 0);
410 dpaa2_flow_extract_key_set(key_info, index, field_size);
413 if (prot == NET_PROT_IP) {
414 if (field == NH_FLD_IP_SRC) {
415 if (key_info->ipv4_dst_offset >= 0) {
416 key_info->ipv4_src_offset =
417 key_info->ipv4_dst_offset +
418 NH_FLD_IPV4_ADDR_SIZE;
420 key_info->ipv4_src_offset =
421 key_info->key_offset[index - 1] +
422 key_info->key_size[index - 1];
424 if (key_info->ipv6_dst_offset >= 0) {
425 key_info->ipv6_src_offset =
426 key_info->ipv6_dst_offset +
427 NH_FLD_IPV6_ADDR_SIZE;
429 key_info->ipv6_src_offset =
430 key_info->key_offset[index - 1] +
431 key_info->key_size[index - 1];
433 } else if (field == NH_FLD_IP_DST) {
434 if (key_info->ipv4_src_offset >= 0) {
435 key_info->ipv4_dst_offset =
436 key_info->ipv4_src_offset +
437 NH_FLD_IPV4_ADDR_SIZE;
439 key_info->ipv4_dst_offset =
440 key_info->key_offset[index - 1] +
441 key_info->key_size[index - 1];
443 if (key_info->ipv6_src_offset >= 0) {
444 key_info->ipv6_dst_offset =
445 key_info->ipv6_src_offset +
446 NH_FLD_IPV6_ADDR_SIZE;
448 key_info->ipv6_dst_offset =
449 key_info->key_offset[index - 1] +
450 key_info->key_size[index - 1];
455 if (index == dpkg->num_extracts) {
456 dpkg->num_extracts++;
462 dpkg->extracts[ip_src].type =
463 DPKG_EXTRACT_FROM_HDR;
464 dpkg->extracts[ip_src].extract.from_hdr.type =
466 dpkg->extracts[ip_src].extract.from_hdr.prot =
468 dpkg->extracts[ip_src].extract.from_hdr.field =
470 dpaa2_flow_extract_key_set(key_info, ip_src, 0);
471 key_info->ipv4_src_offset += field_size;
472 key_info->ipv6_src_offset += field_size;
476 dpkg->extracts[ip_dst].type =
477 DPKG_EXTRACT_FROM_HDR;
478 dpkg->extracts[ip_dst].extract.from_hdr.type =
480 dpkg->extracts[ip_dst].extract.from_hdr.prot =
482 dpkg->extracts[ip_dst].extract.from_hdr.field =
484 dpaa2_flow_extract_key_set(key_info, ip_dst, 0);
485 key_info->ipv4_dst_offset += field_size;
486 key_info->ipv6_dst_offset += field_size;
489 dpkg->num_extracts++;
494 /* Protocol discrimination.
495 * Discriminate IPv4/IPv6/vLan by Eth type.
496 * Discriminate UDP/TCP/ICMP by next proto of IP.
499 dpaa2_flow_proto_discrimination_extract(
500 struct dpaa2_key_extract *key_extract,
501 enum rte_flow_item_type type)
503 if (type == RTE_FLOW_ITEM_TYPE_ETH) {
504 return dpaa2_flow_extract_add(
505 key_extract, NET_PROT_ETH,
508 } else if (type == (enum rte_flow_item_type)
509 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
510 return dpaa2_flow_extract_add(
511 key_extract, NET_PROT_IP,
513 NH_FLD_IP_PROTO_SIZE);
519 static inline int dpaa2_flow_extract_search(
520 struct dpkg_profile_cfg *dpkg,
521 enum net_prot prot, uint32_t field)
525 for (i = 0; i < dpkg->num_extracts; i++) {
526 if (dpkg->extracts[i].extract.from_hdr.prot == prot &&
527 dpkg->extracts[i].extract.from_hdr.field == field) {
535 static inline int dpaa2_flow_extract_key_offset(
536 struct dpaa2_key_extract *key_extract,
537 enum net_prot prot, uint32_t field)
540 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
541 struct dpaa2_key_info *key_info = &key_extract->key_info;
543 if (prot == NET_PROT_IPV4 ||
544 prot == NET_PROT_IPV6)
545 i = dpaa2_flow_extract_search(dpkg, NET_PROT_IP, field);
547 i = dpaa2_flow_extract_search(dpkg, prot, field);
550 if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_SRC)
551 return key_info->ipv4_src_offset;
552 else if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_DST)
553 return key_info->ipv4_dst_offset;
554 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_SRC)
555 return key_info->ipv6_src_offset;
556 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_DST)
557 return key_info->ipv6_dst_offset;
559 return key_info->key_offset[i];
565 struct proto_discrimination {
566 enum rte_flow_item_type type;
574 dpaa2_flow_proto_discrimination_rule(
575 struct dpaa2_dev_priv *priv, struct rte_flow *flow,
576 struct proto_discrimination proto, int group)
586 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
588 field = NH_FLD_ETH_TYPE;
589 } else if (proto.type == DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
591 field = NH_FLD_IP_PROTO;
594 "Only Eth and IP support to discriminate next proto.");
598 offset = dpaa2_flow_extract_key_offset(&priv->extract.qos_key_extract,
601 DPAA2_PMD_ERR("QoS prot %d field %d extract failed",
605 key_iova = flow->qos_rule.key_iova + offset;
606 mask_iova = flow->qos_rule.mask_iova + offset;
607 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
608 eth_type = proto.eth_type;
609 memcpy((void *)key_iova, (const void *)(ð_type),
612 memcpy((void *)mask_iova, (const void *)(ð_type),
615 ip_proto = proto.ip_proto;
616 memcpy((void *)key_iova, (const void *)(&ip_proto),
619 memcpy((void *)mask_iova, (const void *)(&ip_proto),
623 offset = dpaa2_flow_extract_key_offset(
624 &priv->extract.tc_key_extract[group],
627 DPAA2_PMD_ERR("FS prot %d field %d extract failed",
631 key_iova = flow->fs_rule.key_iova + offset;
632 mask_iova = flow->fs_rule.mask_iova + offset;
634 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
635 eth_type = proto.eth_type;
636 memcpy((void *)key_iova, (const void *)(ð_type),
639 memcpy((void *)mask_iova, (const void *)(ð_type),
642 ip_proto = proto.ip_proto;
643 memcpy((void *)key_iova, (const void *)(&ip_proto),
646 memcpy((void *)mask_iova, (const void *)(&ip_proto),
654 dpaa2_flow_rule_data_set(
655 struct dpaa2_key_extract *key_extract,
656 struct dpni_rule_cfg *rule,
657 enum net_prot prot, uint32_t field,
658 const void *key, const void *mask, int size)
660 int offset = dpaa2_flow_extract_key_offset(key_extract,
664 DPAA2_PMD_ERR("prot %d, field %d extract failed",
669 memcpy((void *)(size_t)(rule->key_iova + offset), key, size);
670 memcpy((void *)(size_t)(rule->mask_iova + offset), mask, size);
676 _dpaa2_flow_rule_move_ipaddr_tail(
677 struct dpaa2_key_extract *key_extract,
678 struct dpni_rule_cfg *rule, int src_offset,
679 uint32_t field, bool ipv4)
687 char tmp[NH_FLD_IPV6_ADDR_SIZE];
689 if (field != NH_FLD_IP_SRC &&
690 field != NH_FLD_IP_DST) {
691 DPAA2_PMD_ERR("Field of IP addr reorder must be IP SRC/DST");
695 prot = NET_PROT_IPV4;
697 prot = NET_PROT_IPV6;
698 dst_offset = dpaa2_flow_extract_key_offset(key_extract,
700 if (dst_offset < 0) {
701 DPAA2_PMD_ERR("Field %d reorder extract failed", field);
704 key_src = rule->key_iova + src_offset;
705 mask_src = rule->mask_iova + src_offset;
706 key_dst = rule->key_iova + dst_offset;
707 mask_dst = rule->mask_iova + dst_offset;
709 len = sizeof(rte_be32_t);
711 len = NH_FLD_IPV6_ADDR_SIZE;
713 memcpy(tmp, (char *)key_src, len);
714 memset((char *)key_src, 0, len);
715 memcpy((char *)key_dst, tmp, len);
717 memcpy(tmp, (char *)mask_src, len);
718 memset((char *)mask_src, 0, len);
719 memcpy((char *)mask_dst, tmp, len);
725 dpaa2_flow_rule_move_ipaddr_tail(
726 struct rte_flow *flow, struct dpaa2_dev_priv *priv,
732 if (flow->ipaddr_rule.ipaddr_type == FLOW_NONE_IPADDR)
735 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR)
736 prot = NET_PROT_IPV4;
738 prot = NET_PROT_IPV6;
740 if (flow->ipaddr_rule.qos_ipsrc_offset >= 0) {
741 ret = _dpaa2_flow_rule_move_ipaddr_tail(
742 &priv->extract.qos_key_extract,
744 flow->ipaddr_rule.qos_ipsrc_offset,
745 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
747 DPAA2_PMD_ERR("QoS src address reorder failed");
750 flow->ipaddr_rule.qos_ipsrc_offset =
751 dpaa2_flow_extract_key_offset(
752 &priv->extract.qos_key_extract,
753 prot, NH_FLD_IP_SRC);
756 if (flow->ipaddr_rule.qos_ipdst_offset >= 0) {
757 ret = _dpaa2_flow_rule_move_ipaddr_tail(
758 &priv->extract.qos_key_extract,
760 flow->ipaddr_rule.qos_ipdst_offset,
761 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
763 DPAA2_PMD_ERR("QoS dst address reorder failed");
766 flow->ipaddr_rule.qos_ipdst_offset =
767 dpaa2_flow_extract_key_offset(
768 &priv->extract.qos_key_extract,
769 prot, NH_FLD_IP_DST);
772 if (flow->ipaddr_rule.fs_ipsrc_offset >= 0) {
773 ret = _dpaa2_flow_rule_move_ipaddr_tail(
774 &priv->extract.tc_key_extract[fs_group],
776 flow->ipaddr_rule.fs_ipsrc_offset,
777 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
779 DPAA2_PMD_ERR("FS src address reorder failed");
782 flow->ipaddr_rule.fs_ipsrc_offset =
783 dpaa2_flow_extract_key_offset(
784 &priv->extract.tc_key_extract[fs_group],
785 prot, NH_FLD_IP_SRC);
787 if (flow->ipaddr_rule.fs_ipdst_offset >= 0) {
788 ret = _dpaa2_flow_rule_move_ipaddr_tail(
789 &priv->extract.tc_key_extract[fs_group],
791 flow->ipaddr_rule.fs_ipdst_offset,
792 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
794 DPAA2_PMD_ERR("FS dst address reorder failed");
797 flow->ipaddr_rule.fs_ipdst_offset =
798 dpaa2_flow_extract_key_offset(
799 &priv->extract.tc_key_extract[fs_group],
800 prot, NH_FLD_IP_DST);
807 dpaa2_flow_extract_support(
808 const uint8_t *mask_src,
809 enum rte_flow_item_type type)
813 const char *mask_support = 0;
816 case RTE_FLOW_ITEM_TYPE_ETH:
817 mask_support = (const char *)&dpaa2_flow_item_eth_mask;
818 size = sizeof(struct rte_flow_item_eth);
820 case RTE_FLOW_ITEM_TYPE_VLAN:
821 mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
822 size = sizeof(struct rte_flow_item_vlan);
824 case RTE_FLOW_ITEM_TYPE_IPV4:
825 mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
826 size = sizeof(struct rte_flow_item_ipv4);
828 case RTE_FLOW_ITEM_TYPE_IPV6:
829 mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
830 size = sizeof(struct rte_flow_item_ipv6);
832 case RTE_FLOW_ITEM_TYPE_ICMP:
833 mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
834 size = sizeof(struct rte_flow_item_icmp);
836 case RTE_FLOW_ITEM_TYPE_UDP:
837 mask_support = (const char *)&dpaa2_flow_item_udp_mask;
838 size = sizeof(struct rte_flow_item_udp);
840 case RTE_FLOW_ITEM_TYPE_TCP:
841 mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
842 size = sizeof(struct rte_flow_item_tcp);
844 case RTE_FLOW_ITEM_TYPE_SCTP:
845 mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
846 size = sizeof(struct rte_flow_item_sctp);
848 case RTE_FLOW_ITEM_TYPE_GRE:
849 mask_support = (const char *)&dpaa2_flow_item_gre_mask;
850 size = sizeof(struct rte_flow_item_gre);
856 memcpy(mask, mask_support, size);
858 for (i = 0; i < size; i++)
859 mask[i] = (mask[i] | mask_src[i]);
861 if (memcmp(mask, mask_support, size))
868 dpaa2_configure_flow_eth(struct rte_flow *flow,
869 struct rte_eth_dev *dev,
870 const struct rte_flow_attr *attr,
871 const struct rte_flow_item *pattern,
872 const struct rte_flow_action actions[] __rte_unused,
873 struct rte_flow_error *error __rte_unused,
874 int *device_configured)
879 const struct rte_flow_item_eth *spec, *mask;
881 /* TODO: Currently upper bound of range parameter is not implemented */
882 const struct rte_flow_item_eth *last __rte_unused;
883 struct dpaa2_dev_priv *priv = dev->data->dev_private;
884 const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
888 /* Parse pattern list to get the matching parameters */
889 spec = (const struct rte_flow_item_eth *)pattern->spec;
890 last = (const struct rte_flow_item_eth *)pattern->last;
891 mask = (const struct rte_flow_item_eth *)
892 (pattern->mask ? pattern->mask : &dpaa2_flow_item_eth_mask);
894 /* Don't care any field of eth header,
895 * only care eth protocol.
897 DPAA2_PMD_WARN("No pattern spec for Eth flow, just skip");
901 /* Get traffic class index and flow id to be configured */
903 flow->tc_index = attr->priority;
905 if (dpaa2_flow_extract_support((const uint8_t *)mask,
906 RTE_FLOW_ITEM_TYPE_ETH)) {
907 DPAA2_PMD_WARN("Extract field(s) of ethernet not support.");
912 if (memcmp((const char *)&mask->src, zero_cmp, RTE_ETHER_ADDR_LEN)) {
913 index = dpaa2_flow_extract_search(
914 &priv->extract.qos_key_extract.dpkg,
915 NET_PROT_ETH, NH_FLD_ETH_SA);
917 ret = dpaa2_flow_extract_add(
918 &priv->extract.qos_key_extract,
919 NET_PROT_ETH, NH_FLD_ETH_SA,
922 DPAA2_PMD_ERR("QoS Extract add ETH_SA failed.");
926 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
928 index = dpaa2_flow_extract_search(
929 &priv->extract.tc_key_extract[group].dpkg,
930 NET_PROT_ETH, NH_FLD_ETH_SA);
932 ret = dpaa2_flow_extract_add(
933 &priv->extract.tc_key_extract[group],
934 NET_PROT_ETH, NH_FLD_ETH_SA,
937 DPAA2_PMD_ERR("FS Extract add ETH_SA failed.");
940 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
943 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
946 "Move ipaddr before ETH_SA rule set failed");
950 ret = dpaa2_flow_rule_data_set(
951 &priv->extract.qos_key_extract,
955 &spec->src.addr_bytes,
956 &mask->src.addr_bytes,
957 sizeof(struct rte_ether_addr));
959 DPAA2_PMD_ERR("QoS NH_FLD_ETH_SA rule data set failed");
963 ret = dpaa2_flow_rule_data_set(
964 &priv->extract.tc_key_extract[group],
968 &spec->src.addr_bytes,
969 &mask->src.addr_bytes,
970 sizeof(struct rte_ether_addr));
972 DPAA2_PMD_ERR("FS NH_FLD_ETH_SA rule data set failed");
977 if (memcmp((const char *)&mask->dst, zero_cmp, RTE_ETHER_ADDR_LEN)) {
978 index = dpaa2_flow_extract_search(
979 &priv->extract.qos_key_extract.dpkg,
980 NET_PROT_ETH, NH_FLD_ETH_DA);
982 ret = dpaa2_flow_extract_add(
983 &priv->extract.qos_key_extract,
984 NET_PROT_ETH, NH_FLD_ETH_DA,
987 DPAA2_PMD_ERR("QoS Extract add ETH_DA failed.");
991 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
994 index = dpaa2_flow_extract_search(
995 &priv->extract.tc_key_extract[group].dpkg,
996 NET_PROT_ETH, NH_FLD_ETH_DA);
998 ret = dpaa2_flow_extract_add(
999 &priv->extract.tc_key_extract[group],
1000 NET_PROT_ETH, NH_FLD_ETH_DA,
1001 RTE_ETHER_ADDR_LEN);
1003 DPAA2_PMD_ERR("FS Extract add ETH_DA failed.");
1007 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1010 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1013 "Move ipaddr before ETH DA rule set failed");
1017 ret = dpaa2_flow_rule_data_set(
1018 &priv->extract.qos_key_extract,
1022 &spec->dst.addr_bytes,
1023 &mask->dst.addr_bytes,
1024 sizeof(struct rte_ether_addr));
1026 DPAA2_PMD_ERR("QoS NH_FLD_ETH_DA rule data set failed");
1030 ret = dpaa2_flow_rule_data_set(
1031 &priv->extract.tc_key_extract[group],
1035 &spec->dst.addr_bytes,
1036 &mask->dst.addr_bytes,
1037 sizeof(struct rte_ether_addr));
1039 DPAA2_PMD_ERR("FS NH_FLD_ETH_DA rule data set failed");
1044 if (memcmp((const char *)&mask->type, zero_cmp, sizeof(rte_be16_t))) {
1045 index = dpaa2_flow_extract_search(
1046 &priv->extract.qos_key_extract.dpkg,
1047 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1049 ret = dpaa2_flow_extract_add(
1050 &priv->extract.qos_key_extract,
1051 NET_PROT_ETH, NH_FLD_ETH_TYPE,
1052 RTE_ETHER_TYPE_LEN);
1054 DPAA2_PMD_ERR("QoS Extract add ETH_TYPE failed.");
1058 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1060 index = dpaa2_flow_extract_search(
1061 &priv->extract.tc_key_extract[group].dpkg,
1062 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1064 ret = dpaa2_flow_extract_add(
1065 &priv->extract.tc_key_extract[group],
1066 NET_PROT_ETH, NH_FLD_ETH_TYPE,
1067 RTE_ETHER_TYPE_LEN);
1069 DPAA2_PMD_ERR("FS Extract add ETH_TYPE failed.");
1073 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1076 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1079 "Move ipaddr before ETH TYPE rule set failed");
1083 ret = dpaa2_flow_rule_data_set(
1084 &priv->extract.qos_key_extract,
1090 sizeof(rte_be16_t));
1092 DPAA2_PMD_ERR("QoS NH_FLD_ETH_TYPE rule data set failed");
1096 ret = dpaa2_flow_rule_data_set(
1097 &priv->extract.tc_key_extract[group],
1103 sizeof(rte_be16_t));
1105 DPAA2_PMD_ERR("FS NH_FLD_ETH_TYPE rule data set failed");
1110 (*device_configured) |= local_cfg;
1116 dpaa2_configure_flow_vlan(struct rte_flow *flow,
1117 struct rte_eth_dev *dev,
1118 const struct rte_flow_attr *attr,
1119 const struct rte_flow_item *pattern,
1120 const struct rte_flow_action actions[] __rte_unused,
1121 struct rte_flow_error *error __rte_unused,
1122 int *device_configured)
1127 const struct rte_flow_item_vlan *spec, *mask;
1129 const struct rte_flow_item_vlan *last __rte_unused;
1130 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1132 group = attr->group;
1134 /* Parse pattern list to get the matching parameters */
1135 spec = (const struct rte_flow_item_vlan *)pattern->spec;
1136 last = (const struct rte_flow_item_vlan *)pattern->last;
1137 mask = (const struct rte_flow_item_vlan *)
1138 (pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask);
1140 /* Get traffic class index and flow id to be configured */
1141 flow->tc_id = group;
1142 flow->tc_index = attr->priority;
1145 /* Don't care any field of vlan header,
1146 * only care vlan protocol.
1148 /* Eth type is actually used for vLan classification.
1150 struct proto_discrimination proto;
1152 index = dpaa2_flow_extract_search(
1153 &priv->extract.qos_key_extract.dpkg,
1154 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1156 ret = dpaa2_flow_proto_discrimination_extract(
1157 &priv->extract.qos_key_extract,
1158 RTE_FLOW_ITEM_TYPE_ETH);
1161 "QoS Ext ETH_TYPE to discriminate vLan failed");
1165 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1168 index = dpaa2_flow_extract_search(
1169 &priv->extract.tc_key_extract[group].dpkg,
1170 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1172 ret = dpaa2_flow_proto_discrimination_extract(
1173 &priv->extract.tc_key_extract[group],
1174 RTE_FLOW_ITEM_TYPE_ETH);
1177 "FS Ext ETH_TYPE to discriminate vLan failed.");
1181 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1184 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1187 "Move ipaddr before vLan discrimination set failed");
1191 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1192 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
1193 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1196 DPAA2_PMD_ERR("vLan discrimination rule set failed");
1200 (*device_configured) |= local_cfg;
1205 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1206 RTE_FLOW_ITEM_TYPE_VLAN)) {
1207 DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
1215 index = dpaa2_flow_extract_search(
1216 &priv->extract.qos_key_extract.dpkg,
1217 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1219 ret = dpaa2_flow_extract_add(
1220 &priv->extract.qos_key_extract,
1223 sizeof(rte_be16_t));
1225 DPAA2_PMD_ERR("QoS Extract add VLAN_TCI failed.");
1229 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1232 index = dpaa2_flow_extract_search(
1233 &priv->extract.tc_key_extract[group].dpkg,
1234 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1236 ret = dpaa2_flow_extract_add(
1237 &priv->extract.tc_key_extract[group],
1240 sizeof(rte_be16_t));
1242 DPAA2_PMD_ERR("FS Extract add VLAN_TCI failed.");
1246 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1249 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1252 "Move ipaddr before VLAN TCI rule set failed");
1256 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
1262 sizeof(rte_be16_t));
1264 DPAA2_PMD_ERR("QoS NH_FLD_VLAN_TCI rule data set failed");
1268 ret = dpaa2_flow_rule_data_set(
1269 &priv->extract.tc_key_extract[group],
1275 sizeof(rte_be16_t));
1277 DPAA2_PMD_ERR("FS NH_FLD_VLAN_TCI rule data set failed");
1281 (*device_configured) |= local_cfg;
1287 dpaa2_configure_flow_ip_discrimation(
1288 struct dpaa2_dev_priv *priv, struct rte_flow *flow,
1289 const struct rte_flow_item *pattern,
1290 int *local_cfg, int *device_configured,
1294 struct proto_discrimination proto;
1296 index = dpaa2_flow_extract_search(
1297 &priv->extract.qos_key_extract.dpkg,
1298 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1300 ret = dpaa2_flow_proto_discrimination_extract(
1301 &priv->extract.qos_key_extract,
1302 RTE_FLOW_ITEM_TYPE_ETH);
1305 "QoS Extract ETH_TYPE to discriminate IP failed.");
1308 (*local_cfg) |= DPAA2_QOS_TABLE_RECONFIGURE;
1311 index = dpaa2_flow_extract_search(
1312 &priv->extract.tc_key_extract[group].dpkg,
1313 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1315 ret = dpaa2_flow_proto_discrimination_extract(
1316 &priv->extract.tc_key_extract[group],
1317 RTE_FLOW_ITEM_TYPE_ETH);
1320 "FS Extract ETH_TYPE to discriminate IP failed.");
1323 (*local_cfg) |= DPAA2_FS_TABLE_RECONFIGURE;
1326 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1329 "Move ipaddr before IP discrimination set failed");
1333 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1334 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4)
1335 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
1337 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
1338 ret = dpaa2_flow_proto_discrimination_rule(priv, flow, proto, group);
1340 DPAA2_PMD_ERR("IP discrimination rule set failed");
1344 (*device_configured) |= (*local_cfg);
1351 dpaa2_configure_flow_generic_ip(
1352 struct rte_flow *flow,
1353 struct rte_eth_dev *dev,
1354 const struct rte_flow_attr *attr,
1355 const struct rte_flow_item *pattern,
1356 const struct rte_flow_action actions[] __rte_unused,
1357 struct rte_flow_error *error __rte_unused,
1358 int *device_configured)
1363 const struct rte_flow_item_ipv4 *spec_ipv4 = 0,
1365 const struct rte_flow_item_ipv6 *spec_ipv6 = 0,
1367 const void *key, *mask;
1370 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1371 const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
1374 group = attr->group;
1376 /* Parse pattern list to get the matching parameters */
1377 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1378 spec_ipv4 = (const struct rte_flow_item_ipv4 *)pattern->spec;
1379 mask_ipv4 = (const struct rte_flow_item_ipv4 *)
1380 (pattern->mask ? pattern->mask :
1381 &dpaa2_flow_item_ipv4_mask);
1383 spec_ipv6 = (const struct rte_flow_item_ipv6 *)pattern->spec;
1384 mask_ipv6 = (const struct rte_flow_item_ipv6 *)
1385 (pattern->mask ? pattern->mask :
1386 &dpaa2_flow_item_ipv6_mask);
1389 /* Get traffic class index and flow id to be configured */
1390 flow->tc_id = group;
1391 flow->tc_index = attr->priority;
1393 ret = dpaa2_configure_flow_ip_discrimation(priv,
1394 flow, pattern, &local_cfg,
1395 device_configured, group);
1397 DPAA2_PMD_ERR("IP discrimation failed!");
1401 if (!spec_ipv4 && !spec_ipv6)
1405 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
1406 RTE_FLOW_ITEM_TYPE_IPV4)) {
1407 DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
1414 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
1415 RTE_FLOW_ITEM_TYPE_IPV6)) {
1416 DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
1422 if (mask_ipv4 && (mask_ipv4->hdr.src_addr ||
1423 mask_ipv4->hdr.dst_addr)) {
1424 flow->ipaddr_rule.ipaddr_type = FLOW_IPV4_ADDR;
1425 } else if (mask_ipv6 &&
1426 (memcmp((const char *)mask_ipv6->hdr.src_addr,
1427 zero_cmp, NH_FLD_IPV6_ADDR_SIZE) ||
1428 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1429 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1430 flow->ipaddr_rule.ipaddr_type = FLOW_IPV6_ADDR;
1433 if ((mask_ipv4 && mask_ipv4->hdr.src_addr) ||
1435 memcmp((const char *)mask_ipv6->hdr.src_addr,
1436 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1437 index = dpaa2_flow_extract_search(
1438 &priv->extract.qos_key_extract.dpkg,
1439 NET_PROT_IP, NH_FLD_IP_SRC);
1441 ret = dpaa2_flow_extract_add(
1442 &priv->extract.qos_key_extract,
1447 DPAA2_PMD_ERR("QoS Extract add IP_SRC failed.");
1451 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1454 index = dpaa2_flow_extract_search(
1455 &priv->extract.tc_key_extract[group].dpkg,
1456 NET_PROT_IP, NH_FLD_IP_SRC);
1458 ret = dpaa2_flow_extract_add(
1459 &priv->extract.tc_key_extract[group],
1464 DPAA2_PMD_ERR("FS Extract add IP_SRC failed.");
1468 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1472 key = &spec_ipv4->hdr.src_addr;
1474 key = &spec_ipv6->hdr.src_addr[0];
1476 mask = &mask_ipv4->hdr.src_addr;
1477 size = NH_FLD_IPV4_ADDR_SIZE;
1478 prot = NET_PROT_IPV4;
1480 mask = &mask_ipv6->hdr.src_addr[0];
1481 size = NH_FLD_IPV6_ADDR_SIZE;
1482 prot = NET_PROT_IPV6;
1485 ret = dpaa2_flow_rule_data_set(
1486 &priv->extract.qos_key_extract,
1488 prot, NH_FLD_IP_SRC,
1491 DPAA2_PMD_ERR("QoS NH_FLD_IP_SRC rule data set failed");
1495 ret = dpaa2_flow_rule_data_set(
1496 &priv->extract.tc_key_extract[group],
1498 prot, NH_FLD_IP_SRC,
1501 DPAA2_PMD_ERR("FS NH_FLD_IP_SRC rule data set failed");
1505 flow->ipaddr_rule.qos_ipsrc_offset =
1506 dpaa2_flow_extract_key_offset(
1507 &priv->extract.qos_key_extract,
1508 prot, NH_FLD_IP_SRC);
1509 flow->ipaddr_rule.fs_ipsrc_offset =
1510 dpaa2_flow_extract_key_offset(
1511 &priv->extract.tc_key_extract[group],
1512 prot, NH_FLD_IP_SRC);
1515 if ((mask_ipv4 && mask_ipv4->hdr.dst_addr) ||
1517 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1518 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1519 index = dpaa2_flow_extract_search(
1520 &priv->extract.qos_key_extract.dpkg,
1521 NET_PROT_IP, NH_FLD_IP_DST);
1524 size = NH_FLD_IPV4_ADDR_SIZE;
1526 size = NH_FLD_IPV6_ADDR_SIZE;
1527 ret = dpaa2_flow_extract_add(
1528 &priv->extract.qos_key_extract,
1533 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1537 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1540 index = dpaa2_flow_extract_search(
1541 &priv->extract.tc_key_extract[group].dpkg,
1542 NET_PROT_IP, NH_FLD_IP_DST);
1545 size = NH_FLD_IPV4_ADDR_SIZE;
1547 size = NH_FLD_IPV6_ADDR_SIZE;
1548 ret = dpaa2_flow_extract_add(
1549 &priv->extract.tc_key_extract[group],
1554 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1558 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1562 key = &spec_ipv4->hdr.dst_addr;
1564 key = spec_ipv6->hdr.dst_addr;
1566 mask = &mask_ipv4->hdr.dst_addr;
1567 size = NH_FLD_IPV4_ADDR_SIZE;
1568 prot = NET_PROT_IPV4;
1570 mask = &mask_ipv6->hdr.dst_addr[0];
1571 size = NH_FLD_IPV6_ADDR_SIZE;
1572 prot = NET_PROT_IPV6;
1575 ret = dpaa2_flow_rule_data_set(
1576 &priv->extract.qos_key_extract,
1578 prot, NH_FLD_IP_DST,
1581 DPAA2_PMD_ERR("QoS NH_FLD_IP_DST rule data set failed");
1585 ret = dpaa2_flow_rule_data_set(
1586 &priv->extract.tc_key_extract[group],
1588 prot, NH_FLD_IP_DST,
1591 DPAA2_PMD_ERR("FS NH_FLD_IP_DST rule data set failed");
1594 flow->ipaddr_rule.qos_ipdst_offset =
1595 dpaa2_flow_extract_key_offset(
1596 &priv->extract.qos_key_extract,
1597 prot, NH_FLD_IP_DST);
1598 flow->ipaddr_rule.fs_ipdst_offset =
1599 dpaa2_flow_extract_key_offset(
1600 &priv->extract.tc_key_extract[group],
1601 prot, NH_FLD_IP_DST);
1604 if ((mask_ipv4 && mask_ipv4->hdr.next_proto_id) ||
1605 (mask_ipv6 && mask_ipv6->hdr.proto)) {
1606 index = dpaa2_flow_extract_search(
1607 &priv->extract.qos_key_extract.dpkg,
1608 NET_PROT_IP, NH_FLD_IP_PROTO);
1610 ret = dpaa2_flow_extract_add(
1611 &priv->extract.qos_key_extract,
1614 NH_FLD_IP_PROTO_SIZE);
1616 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1620 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1623 index = dpaa2_flow_extract_search(
1624 &priv->extract.tc_key_extract[group].dpkg,
1625 NET_PROT_IP, NH_FLD_IP_PROTO);
1627 ret = dpaa2_flow_extract_add(
1628 &priv->extract.tc_key_extract[group],
1631 NH_FLD_IP_PROTO_SIZE);
1633 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1637 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1640 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1643 "Move ipaddr after NH_FLD_IP_PROTO rule set failed");
1648 key = &spec_ipv4->hdr.next_proto_id;
1650 key = &spec_ipv6->hdr.proto;
1652 mask = &mask_ipv4->hdr.next_proto_id;
1654 mask = &mask_ipv6->hdr.proto;
1656 ret = dpaa2_flow_rule_data_set(
1657 &priv->extract.qos_key_extract,
1661 key, mask, NH_FLD_IP_PROTO_SIZE);
1663 DPAA2_PMD_ERR("QoS NH_FLD_IP_PROTO rule data set failed");
1667 ret = dpaa2_flow_rule_data_set(
1668 &priv->extract.tc_key_extract[group],
1672 key, mask, NH_FLD_IP_PROTO_SIZE);
1674 DPAA2_PMD_ERR("FS NH_FLD_IP_PROTO rule data set failed");
1679 (*device_configured) |= local_cfg;
1685 dpaa2_configure_flow_icmp(struct rte_flow *flow,
1686 struct rte_eth_dev *dev,
1687 const struct rte_flow_attr *attr,
1688 const struct rte_flow_item *pattern,
1689 const struct rte_flow_action actions[] __rte_unused,
1690 struct rte_flow_error *error __rte_unused,
1691 int *device_configured)
1696 const struct rte_flow_item_icmp *spec, *mask;
1698 const struct rte_flow_item_icmp *last __rte_unused;
1699 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1701 group = attr->group;
1703 /* Parse pattern list to get the matching parameters */
1704 spec = (const struct rte_flow_item_icmp *)pattern->spec;
1705 last = (const struct rte_flow_item_icmp *)pattern->last;
1706 mask = (const struct rte_flow_item_icmp *)
1707 (pattern->mask ? pattern->mask : &dpaa2_flow_item_icmp_mask);
1709 /* Get traffic class index and flow id to be configured */
1710 flow->tc_id = group;
1711 flow->tc_index = attr->priority;
1714 /* Don't care any field of ICMP header,
1715 * only care ICMP protocol.
1716 * Example: flow create 0 ingress pattern icmp /
1718 /* Next proto of Generical IP is actually used
1719 * for ICMP identification.
1721 struct proto_discrimination proto;
1723 index = dpaa2_flow_extract_search(
1724 &priv->extract.qos_key_extract.dpkg,
1725 NET_PROT_IP, NH_FLD_IP_PROTO);
1727 ret = dpaa2_flow_proto_discrimination_extract(
1728 &priv->extract.qos_key_extract,
1729 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1732 "QoS Extract IP protocol to discriminate ICMP failed.");
1736 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1739 index = dpaa2_flow_extract_search(
1740 &priv->extract.tc_key_extract[group].dpkg,
1741 NET_PROT_IP, NH_FLD_IP_PROTO);
1743 ret = dpaa2_flow_proto_discrimination_extract(
1744 &priv->extract.tc_key_extract[group],
1745 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1748 "FS Extract IP protocol to discriminate ICMP failed.");
1752 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1755 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1758 "Move IP addr before ICMP discrimination set failed");
1762 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1763 proto.ip_proto = IPPROTO_ICMP;
1764 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1767 DPAA2_PMD_ERR("ICMP discrimination rule set failed");
1771 (*device_configured) |= local_cfg;
1776 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1777 RTE_FLOW_ITEM_TYPE_ICMP)) {
1778 DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
1783 if (mask->hdr.icmp_type) {
1784 index = dpaa2_flow_extract_search(
1785 &priv->extract.qos_key_extract.dpkg,
1786 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1788 ret = dpaa2_flow_extract_add(
1789 &priv->extract.qos_key_extract,
1792 NH_FLD_ICMP_TYPE_SIZE);
1794 DPAA2_PMD_ERR("QoS Extract add ICMP_TYPE failed.");
1798 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1801 index = dpaa2_flow_extract_search(
1802 &priv->extract.tc_key_extract[group].dpkg,
1803 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1805 ret = dpaa2_flow_extract_add(
1806 &priv->extract.tc_key_extract[group],
1809 NH_FLD_ICMP_TYPE_SIZE);
1811 DPAA2_PMD_ERR("FS Extract add ICMP_TYPE failed.");
1815 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1818 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1821 "Move ipaddr before ICMP TYPE set failed");
1825 ret = dpaa2_flow_rule_data_set(
1826 &priv->extract.qos_key_extract,
1830 &spec->hdr.icmp_type,
1831 &mask->hdr.icmp_type,
1832 NH_FLD_ICMP_TYPE_SIZE);
1834 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_TYPE rule data set failed");
1838 ret = dpaa2_flow_rule_data_set(
1839 &priv->extract.tc_key_extract[group],
1843 &spec->hdr.icmp_type,
1844 &mask->hdr.icmp_type,
1845 NH_FLD_ICMP_TYPE_SIZE);
1847 DPAA2_PMD_ERR("FS NH_FLD_ICMP_TYPE rule data set failed");
1852 if (mask->hdr.icmp_code) {
1853 index = dpaa2_flow_extract_search(
1854 &priv->extract.qos_key_extract.dpkg,
1855 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1857 ret = dpaa2_flow_extract_add(
1858 &priv->extract.qos_key_extract,
1861 NH_FLD_ICMP_CODE_SIZE);
1863 DPAA2_PMD_ERR("QoS Extract add ICMP_CODE failed.");
1867 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1870 index = dpaa2_flow_extract_search(
1871 &priv->extract.tc_key_extract[group].dpkg,
1872 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1874 ret = dpaa2_flow_extract_add(
1875 &priv->extract.tc_key_extract[group],
1878 NH_FLD_ICMP_CODE_SIZE);
1880 DPAA2_PMD_ERR("FS Extract add ICMP_CODE failed.");
1884 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1887 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1890 "Move ipaddr after ICMP CODE set failed");
1894 ret = dpaa2_flow_rule_data_set(
1895 &priv->extract.qos_key_extract,
1899 &spec->hdr.icmp_code,
1900 &mask->hdr.icmp_code,
1901 NH_FLD_ICMP_CODE_SIZE);
1903 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_CODE rule data set failed");
1907 ret = dpaa2_flow_rule_data_set(
1908 &priv->extract.tc_key_extract[group],
1912 &spec->hdr.icmp_code,
1913 &mask->hdr.icmp_code,
1914 NH_FLD_ICMP_CODE_SIZE);
1916 DPAA2_PMD_ERR("FS NH_FLD_ICMP_CODE rule data set failed");
1921 (*device_configured) |= local_cfg;
1927 dpaa2_configure_flow_udp(struct rte_flow *flow,
1928 struct rte_eth_dev *dev,
1929 const struct rte_flow_attr *attr,
1930 const struct rte_flow_item *pattern,
1931 const struct rte_flow_action actions[] __rte_unused,
1932 struct rte_flow_error *error __rte_unused,
1933 int *device_configured)
1938 const struct rte_flow_item_udp *spec, *mask;
1940 const struct rte_flow_item_udp *last __rte_unused;
1941 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1943 group = attr->group;
1945 /* Parse pattern list to get the matching parameters */
1946 spec = (const struct rte_flow_item_udp *)pattern->spec;
1947 last = (const struct rte_flow_item_udp *)pattern->last;
1948 mask = (const struct rte_flow_item_udp *)
1949 (pattern->mask ? pattern->mask : &dpaa2_flow_item_udp_mask);
1951 /* Get traffic class index and flow id to be configured */
1952 flow->tc_id = group;
1953 flow->tc_index = attr->priority;
1955 if (!spec || !mc_l4_port_identification) {
1956 struct proto_discrimination proto;
1958 index = dpaa2_flow_extract_search(
1959 &priv->extract.qos_key_extract.dpkg,
1960 NET_PROT_IP, NH_FLD_IP_PROTO);
1962 ret = dpaa2_flow_proto_discrimination_extract(
1963 &priv->extract.qos_key_extract,
1964 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1967 "QoS Extract IP protocol to discriminate UDP failed.");
1971 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1974 index = dpaa2_flow_extract_search(
1975 &priv->extract.tc_key_extract[group].dpkg,
1976 NET_PROT_IP, NH_FLD_IP_PROTO);
1978 ret = dpaa2_flow_proto_discrimination_extract(
1979 &priv->extract.tc_key_extract[group],
1980 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1983 "FS Extract IP protocol to discriminate UDP failed.");
1987 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1990 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1993 "Move IP addr before UDP discrimination set failed");
1997 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1998 proto.ip_proto = IPPROTO_UDP;
1999 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2002 DPAA2_PMD_ERR("UDP discrimination rule set failed");
2006 (*device_configured) |= local_cfg;
2012 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2013 RTE_FLOW_ITEM_TYPE_UDP)) {
2014 DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
2019 if (mask->hdr.src_port) {
2020 index = dpaa2_flow_extract_search(
2021 &priv->extract.qos_key_extract.dpkg,
2022 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
2024 ret = dpaa2_flow_extract_add(
2025 &priv->extract.qos_key_extract,
2027 NH_FLD_UDP_PORT_SRC,
2028 NH_FLD_UDP_PORT_SIZE);
2030 DPAA2_PMD_ERR("QoS Extract add UDP_SRC failed.");
2034 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2037 index = dpaa2_flow_extract_search(
2038 &priv->extract.tc_key_extract[group].dpkg,
2039 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
2041 ret = dpaa2_flow_extract_add(
2042 &priv->extract.tc_key_extract[group],
2044 NH_FLD_UDP_PORT_SRC,
2045 NH_FLD_UDP_PORT_SIZE);
2047 DPAA2_PMD_ERR("FS Extract add UDP_SRC failed.");
2051 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2054 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2057 "Move ipaddr before UDP_PORT_SRC set failed");
2061 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
2064 NH_FLD_UDP_PORT_SRC,
2065 &spec->hdr.src_port,
2066 &mask->hdr.src_port,
2067 NH_FLD_UDP_PORT_SIZE);
2070 "QoS NH_FLD_UDP_PORT_SRC rule data set failed");
2074 ret = dpaa2_flow_rule_data_set(
2075 &priv->extract.tc_key_extract[group],
2078 NH_FLD_UDP_PORT_SRC,
2079 &spec->hdr.src_port,
2080 &mask->hdr.src_port,
2081 NH_FLD_UDP_PORT_SIZE);
2084 "FS NH_FLD_UDP_PORT_SRC rule data set failed");
2089 if (mask->hdr.dst_port) {
2090 index = dpaa2_flow_extract_search(
2091 &priv->extract.qos_key_extract.dpkg,
2092 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
2094 ret = dpaa2_flow_extract_add(
2095 &priv->extract.qos_key_extract,
2097 NH_FLD_UDP_PORT_DST,
2098 NH_FLD_UDP_PORT_SIZE);
2100 DPAA2_PMD_ERR("QoS Extract add UDP_DST failed.");
2104 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2107 index = dpaa2_flow_extract_search(
2108 &priv->extract.tc_key_extract[group].dpkg,
2109 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
2111 ret = dpaa2_flow_extract_add(
2112 &priv->extract.tc_key_extract[group],
2114 NH_FLD_UDP_PORT_DST,
2115 NH_FLD_UDP_PORT_SIZE);
2117 DPAA2_PMD_ERR("FS Extract add UDP_DST failed.");
2121 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2124 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2127 "Move ipaddr before UDP_PORT_DST set failed");
2131 ret = dpaa2_flow_rule_data_set(
2132 &priv->extract.qos_key_extract,
2135 NH_FLD_UDP_PORT_DST,
2136 &spec->hdr.dst_port,
2137 &mask->hdr.dst_port,
2138 NH_FLD_UDP_PORT_SIZE);
2141 "QoS NH_FLD_UDP_PORT_DST rule data set failed");
2145 ret = dpaa2_flow_rule_data_set(
2146 &priv->extract.tc_key_extract[group],
2149 NH_FLD_UDP_PORT_DST,
2150 &spec->hdr.dst_port,
2151 &mask->hdr.dst_port,
2152 NH_FLD_UDP_PORT_SIZE);
2155 "FS NH_FLD_UDP_PORT_DST rule data set failed");
2160 (*device_configured) |= local_cfg;
2166 dpaa2_configure_flow_tcp(struct rte_flow *flow,
2167 struct rte_eth_dev *dev,
2168 const struct rte_flow_attr *attr,
2169 const struct rte_flow_item *pattern,
2170 const struct rte_flow_action actions[] __rte_unused,
2171 struct rte_flow_error *error __rte_unused,
2172 int *device_configured)
2177 const struct rte_flow_item_tcp *spec, *mask;
2179 const struct rte_flow_item_tcp *last __rte_unused;
2180 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2182 group = attr->group;
2184 /* Parse pattern list to get the matching parameters */
2185 spec = (const struct rte_flow_item_tcp *)pattern->spec;
2186 last = (const struct rte_flow_item_tcp *)pattern->last;
2187 mask = (const struct rte_flow_item_tcp *)
2188 (pattern->mask ? pattern->mask : &dpaa2_flow_item_tcp_mask);
2190 /* Get traffic class index and flow id to be configured */
2191 flow->tc_id = group;
2192 flow->tc_index = attr->priority;
2194 if (!spec || !mc_l4_port_identification) {
2195 struct proto_discrimination proto;
2197 index = dpaa2_flow_extract_search(
2198 &priv->extract.qos_key_extract.dpkg,
2199 NET_PROT_IP, NH_FLD_IP_PROTO);
2201 ret = dpaa2_flow_proto_discrimination_extract(
2202 &priv->extract.qos_key_extract,
2203 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2206 "QoS Extract IP protocol to discriminate TCP failed.");
2210 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2213 index = dpaa2_flow_extract_search(
2214 &priv->extract.tc_key_extract[group].dpkg,
2215 NET_PROT_IP, NH_FLD_IP_PROTO);
2217 ret = dpaa2_flow_proto_discrimination_extract(
2218 &priv->extract.tc_key_extract[group],
2219 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2222 "FS Extract IP protocol to discriminate TCP failed.");
2226 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2229 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2232 "Move IP addr before TCP discrimination set failed");
2236 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2237 proto.ip_proto = IPPROTO_TCP;
2238 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2241 DPAA2_PMD_ERR("TCP discrimination rule set failed");
2245 (*device_configured) |= local_cfg;
2251 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2252 RTE_FLOW_ITEM_TYPE_TCP)) {
2253 DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
2258 if (mask->hdr.src_port) {
2259 index = dpaa2_flow_extract_search(
2260 &priv->extract.qos_key_extract.dpkg,
2261 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2263 ret = dpaa2_flow_extract_add(
2264 &priv->extract.qos_key_extract,
2266 NH_FLD_TCP_PORT_SRC,
2267 NH_FLD_TCP_PORT_SIZE);
2269 DPAA2_PMD_ERR("QoS Extract add TCP_SRC failed.");
2273 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2276 index = dpaa2_flow_extract_search(
2277 &priv->extract.tc_key_extract[group].dpkg,
2278 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2280 ret = dpaa2_flow_extract_add(
2281 &priv->extract.tc_key_extract[group],
2283 NH_FLD_TCP_PORT_SRC,
2284 NH_FLD_TCP_PORT_SIZE);
2286 DPAA2_PMD_ERR("FS Extract add TCP_SRC failed.");
2290 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2293 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2296 "Move ipaddr before TCP_PORT_SRC set failed");
2300 ret = dpaa2_flow_rule_data_set(
2301 &priv->extract.qos_key_extract,
2304 NH_FLD_TCP_PORT_SRC,
2305 &spec->hdr.src_port,
2306 &mask->hdr.src_port,
2307 NH_FLD_TCP_PORT_SIZE);
2310 "QoS NH_FLD_TCP_PORT_SRC rule data set failed");
2314 ret = dpaa2_flow_rule_data_set(
2315 &priv->extract.tc_key_extract[group],
2318 NH_FLD_TCP_PORT_SRC,
2319 &spec->hdr.src_port,
2320 &mask->hdr.src_port,
2321 NH_FLD_TCP_PORT_SIZE);
2324 "FS NH_FLD_TCP_PORT_SRC rule data set failed");
2329 if (mask->hdr.dst_port) {
2330 index = dpaa2_flow_extract_search(
2331 &priv->extract.qos_key_extract.dpkg,
2332 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2334 ret = dpaa2_flow_extract_add(
2335 &priv->extract.qos_key_extract,
2337 NH_FLD_TCP_PORT_DST,
2338 NH_FLD_TCP_PORT_SIZE);
2340 DPAA2_PMD_ERR("QoS Extract add TCP_DST failed.");
2344 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2347 index = dpaa2_flow_extract_search(
2348 &priv->extract.tc_key_extract[group].dpkg,
2349 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2351 ret = dpaa2_flow_extract_add(
2352 &priv->extract.tc_key_extract[group],
2354 NH_FLD_TCP_PORT_DST,
2355 NH_FLD_TCP_PORT_SIZE);
2357 DPAA2_PMD_ERR("FS Extract add TCP_DST failed.");
2361 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2364 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2367 "Move ipaddr before TCP_PORT_DST set failed");
2371 ret = dpaa2_flow_rule_data_set(
2372 &priv->extract.qos_key_extract,
2375 NH_FLD_TCP_PORT_DST,
2376 &spec->hdr.dst_port,
2377 &mask->hdr.dst_port,
2378 NH_FLD_TCP_PORT_SIZE);
2381 "QoS NH_FLD_TCP_PORT_DST rule data set failed");
2385 ret = dpaa2_flow_rule_data_set(
2386 &priv->extract.tc_key_extract[group],
2389 NH_FLD_TCP_PORT_DST,
2390 &spec->hdr.dst_port,
2391 &mask->hdr.dst_port,
2392 NH_FLD_TCP_PORT_SIZE);
2395 "FS NH_FLD_TCP_PORT_DST rule data set failed");
2400 (*device_configured) |= local_cfg;
2406 dpaa2_configure_flow_sctp(struct rte_flow *flow,
2407 struct rte_eth_dev *dev,
2408 const struct rte_flow_attr *attr,
2409 const struct rte_flow_item *pattern,
2410 const struct rte_flow_action actions[] __rte_unused,
2411 struct rte_flow_error *error __rte_unused,
2412 int *device_configured)
2417 const struct rte_flow_item_sctp *spec, *mask;
2419 const struct rte_flow_item_sctp *last __rte_unused;
2420 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2422 group = attr->group;
2424 /* Parse pattern list to get the matching parameters */
2425 spec = (const struct rte_flow_item_sctp *)pattern->spec;
2426 last = (const struct rte_flow_item_sctp *)pattern->last;
2427 mask = (const struct rte_flow_item_sctp *)
2428 (pattern->mask ? pattern->mask :
2429 &dpaa2_flow_item_sctp_mask);
2431 /* Get traffic class index and flow id to be configured */
2432 flow->tc_id = group;
2433 flow->tc_index = attr->priority;
2435 if (!spec || !mc_l4_port_identification) {
2436 struct proto_discrimination proto;
2438 index = dpaa2_flow_extract_search(
2439 &priv->extract.qos_key_extract.dpkg,
2440 NET_PROT_IP, NH_FLD_IP_PROTO);
2442 ret = dpaa2_flow_proto_discrimination_extract(
2443 &priv->extract.qos_key_extract,
2444 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2447 "QoS Extract IP protocol to discriminate SCTP failed.");
2451 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2454 index = dpaa2_flow_extract_search(
2455 &priv->extract.tc_key_extract[group].dpkg,
2456 NET_PROT_IP, NH_FLD_IP_PROTO);
2458 ret = dpaa2_flow_proto_discrimination_extract(
2459 &priv->extract.tc_key_extract[group],
2460 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2463 "FS Extract IP protocol to discriminate SCTP failed.");
2467 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2470 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2473 "Move ipaddr before SCTP discrimination set failed");
2477 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2478 proto.ip_proto = IPPROTO_SCTP;
2479 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2482 DPAA2_PMD_ERR("SCTP discrimination rule set failed");
2486 (*device_configured) |= local_cfg;
2492 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2493 RTE_FLOW_ITEM_TYPE_SCTP)) {
2494 DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
2499 if (mask->hdr.src_port) {
2500 index = dpaa2_flow_extract_search(
2501 &priv->extract.qos_key_extract.dpkg,
2502 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2504 ret = dpaa2_flow_extract_add(
2505 &priv->extract.qos_key_extract,
2507 NH_FLD_SCTP_PORT_SRC,
2508 NH_FLD_SCTP_PORT_SIZE);
2510 DPAA2_PMD_ERR("QoS Extract add SCTP_SRC failed.");
2514 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2517 index = dpaa2_flow_extract_search(
2518 &priv->extract.tc_key_extract[group].dpkg,
2519 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2521 ret = dpaa2_flow_extract_add(
2522 &priv->extract.tc_key_extract[group],
2524 NH_FLD_SCTP_PORT_SRC,
2525 NH_FLD_SCTP_PORT_SIZE);
2527 DPAA2_PMD_ERR("FS Extract add SCTP_SRC failed.");
2531 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2534 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2537 "Move ipaddr before SCTP_PORT_SRC set failed");
2541 ret = dpaa2_flow_rule_data_set(
2542 &priv->extract.qos_key_extract,
2545 NH_FLD_SCTP_PORT_SRC,
2546 &spec->hdr.src_port,
2547 &mask->hdr.src_port,
2548 NH_FLD_SCTP_PORT_SIZE);
2551 "QoS NH_FLD_SCTP_PORT_SRC rule data set failed");
2555 ret = dpaa2_flow_rule_data_set(
2556 &priv->extract.tc_key_extract[group],
2559 NH_FLD_SCTP_PORT_SRC,
2560 &spec->hdr.src_port,
2561 &mask->hdr.src_port,
2562 NH_FLD_SCTP_PORT_SIZE);
2565 "FS NH_FLD_SCTP_PORT_SRC rule data set failed");
2570 if (mask->hdr.dst_port) {
2571 index = dpaa2_flow_extract_search(
2572 &priv->extract.qos_key_extract.dpkg,
2573 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2575 ret = dpaa2_flow_extract_add(
2576 &priv->extract.qos_key_extract,
2578 NH_FLD_SCTP_PORT_DST,
2579 NH_FLD_SCTP_PORT_SIZE);
2581 DPAA2_PMD_ERR("QoS Extract add SCTP_DST failed.");
2585 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2588 index = dpaa2_flow_extract_search(
2589 &priv->extract.tc_key_extract[group].dpkg,
2590 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2592 ret = dpaa2_flow_extract_add(
2593 &priv->extract.tc_key_extract[group],
2595 NH_FLD_SCTP_PORT_DST,
2596 NH_FLD_SCTP_PORT_SIZE);
2598 DPAA2_PMD_ERR("FS Extract add SCTP_DST failed.");
2602 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2605 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2608 "Move ipaddr before SCTP_PORT_DST set failed");
2612 ret = dpaa2_flow_rule_data_set(
2613 &priv->extract.qos_key_extract,
2616 NH_FLD_SCTP_PORT_DST,
2617 &spec->hdr.dst_port,
2618 &mask->hdr.dst_port,
2619 NH_FLD_SCTP_PORT_SIZE);
2622 "QoS NH_FLD_SCTP_PORT_DST rule data set failed");
2626 ret = dpaa2_flow_rule_data_set(
2627 &priv->extract.tc_key_extract[group],
2630 NH_FLD_SCTP_PORT_DST,
2631 &spec->hdr.dst_port,
2632 &mask->hdr.dst_port,
2633 NH_FLD_SCTP_PORT_SIZE);
2636 "FS NH_FLD_SCTP_PORT_DST rule data set failed");
2641 (*device_configured) |= local_cfg;
2647 dpaa2_configure_flow_gre(struct rte_flow *flow,
2648 struct rte_eth_dev *dev,
2649 const struct rte_flow_attr *attr,
2650 const struct rte_flow_item *pattern,
2651 const struct rte_flow_action actions[] __rte_unused,
2652 struct rte_flow_error *error __rte_unused,
2653 int *device_configured)
2658 const struct rte_flow_item_gre *spec, *mask;
2660 const struct rte_flow_item_gre *last __rte_unused;
2661 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2663 group = attr->group;
2665 /* Parse pattern list to get the matching parameters */
2666 spec = (const struct rte_flow_item_gre *)pattern->spec;
2667 last = (const struct rte_flow_item_gre *)pattern->last;
2668 mask = (const struct rte_flow_item_gre *)
2669 (pattern->mask ? pattern->mask : &dpaa2_flow_item_gre_mask);
2671 /* Get traffic class index and flow id to be configured */
2672 flow->tc_id = group;
2673 flow->tc_index = attr->priority;
2676 struct proto_discrimination proto;
2678 index = dpaa2_flow_extract_search(
2679 &priv->extract.qos_key_extract.dpkg,
2680 NET_PROT_IP, NH_FLD_IP_PROTO);
2682 ret = dpaa2_flow_proto_discrimination_extract(
2683 &priv->extract.qos_key_extract,
2684 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2687 "QoS Extract IP protocol to discriminate GRE failed.");
2691 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2694 index = dpaa2_flow_extract_search(
2695 &priv->extract.tc_key_extract[group].dpkg,
2696 NET_PROT_IP, NH_FLD_IP_PROTO);
2698 ret = dpaa2_flow_proto_discrimination_extract(
2699 &priv->extract.tc_key_extract[group],
2700 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2703 "FS Extract IP protocol to discriminate GRE failed.");
2707 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2710 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2713 "Move IP addr before GRE discrimination set failed");
2717 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2718 proto.ip_proto = IPPROTO_GRE;
2719 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2722 DPAA2_PMD_ERR("GRE discrimination rule set failed");
2726 (*device_configured) |= local_cfg;
2731 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2732 RTE_FLOW_ITEM_TYPE_GRE)) {
2733 DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
2738 if (!mask->protocol)
2741 index = dpaa2_flow_extract_search(
2742 &priv->extract.qos_key_extract.dpkg,
2743 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2745 ret = dpaa2_flow_extract_add(
2746 &priv->extract.qos_key_extract,
2749 sizeof(rte_be16_t));
2751 DPAA2_PMD_ERR("QoS Extract add GRE_TYPE failed.");
2755 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2758 index = dpaa2_flow_extract_search(
2759 &priv->extract.tc_key_extract[group].dpkg,
2760 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2762 ret = dpaa2_flow_extract_add(
2763 &priv->extract.tc_key_extract[group],
2766 sizeof(rte_be16_t));
2768 DPAA2_PMD_ERR("FS Extract add GRE_TYPE failed.");
2772 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2775 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2778 "Move ipaddr before GRE_TYPE set failed");
2782 ret = dpaa2_flow_rule_data_set(
2783 &priv->extract.qos_key_extract,
2789 sizeof(rte_be16_t));
2792 "QoS NH_FLD_GRE_TYPE rule data set failed");
2796 ret = dpaa2_flow_rule_data_set(
2797 &priv->extract.tc_key_extract[group],
2803 sizeof(rte_be16_t));
2806 "FS NH_FLD_GRE_TYPE rule data set failed");
2810 (*device_configured) |= local_cfg;
2815 /* The existing QoS/FS entry with IP address(es)
2816 * needs update after
2817 * new extract(s) are inserted before IP
2818 * address(es) extract(s).
2821 dpaa2_flow_entry_update(
2822 struct dpaa2_dev_priv *priv, uint8_t tc_id)
2824 struct rte_flow *curr = LIST_FIRST(&priv->flows);
2825 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
2827 int qos_ipsrc_offset = -1, qos_ipdst_offset = -1;
2828 int fs_ipsrc_offset = -1, fs_ipdst_offset = -1;
2829 struct dpaa2_key_extract *qos_key_extract =
2830 &priv->extract.qos_key_extract;
2831 struct dpaa2_key_extract *tc_key_extract =
2832 &priv->extract.tc_key_extract[tc_id];
2833 char ipsrc_key[NH_FLD_IPV6_ADDR_SIZE];
2834 char ipdst_key[NH_FLD_IPV6_ADDR_SIZE];
2835 char ipsrc_mask[NH_FLD_IPV6_ADDR_SIZE];
2836 char ipdst_mask[NH_FLD_IPV6_ADDR_SIZE];
2837 int extend = -1, extend1, size = -1;
2841 if (curr->ipaddr_rule.ipaddr_type ==
2843 curr = LIST_NEXT(curr, next);
2847 if (curr->ipaddr_rule.ipaddr_type ==
2850 qos_key_extract->key_info.ipv4_src_offset;
2852 qos_key_extract->key_info.ipv4_dst_offset;
2854 tc_key_extract->key_info.ipv4_src_offset;
2856 tc_key_extract->key_info.ipv4_dst_offset;
2857 size = NH_FLD_IPV4_ADDR_SIZE;
2860 qos_key_extract->key_info.ipv6_src_offset;
2862 qos_key_extract->key_info.ipv6_dst_offset;
2864 tc_key_extract->key_info.ipv6_src_offset;
2866 tc_key_extract->key_info.ipv6_dst_offset;
2867 size = NH_FLD_IPV6_ADDR_SIZE;
2870 qos_index = curr->tc_id * priv->fs_entries +
2873 dpaa2_flow_qos_entry_log("Before update", curr, qos_index);
2875 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
2876 priv->token, &curr->qos_rule);
2878 DPAA2_PMD_ERR("Qos entry remove failed.");
2884 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2885 RTE_ASSERT(qos_ipsrc_offset >=
2886 curr->ipaddr_rule.qos_ipsrc_offset);
2887 extend1 = qos_ipsrc_offset -
2888 curr->ipaddr_rule.qos_ipsrc_offset;
2890 RTE_ASSERT(extend == extend1);
2894 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2895 (size == NH_FLD_IPV6_ADDR_SIZE));
2898 (char *)(size_t)curr->qos_rule.key_iova +
2899 curr->ipaddr_rule.qos_ipsrc_offset,
2901 memset((char *)(size_t)curr->qos_rule.key_iova +
2902 curr->ipaddr_rule.qos_ipsrc_offset,
2906 (char *)(size_t)curr->qos_rule.mask_iova +
2907 curr->ipaddr_rule.qos_ipsrc_offset,
2909 memset((char *)(size_t)curr->qos_rule.mask_iova +
2910 curr->ipaddr_rule.qos_ipsrc_offset,
2913 curr->ipaddr_rule.qos_ipsrc_offset = qos_ipsrc_offset;
2916 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2917 RTE_ASSERT(qos_ipdst_offset >=
2918 curr->ipaddr_rule.qos_ipdst_offset);
2919 extend1 = qos_ipdst_offset -
2920 curr->ipaddr_rule.qos_ipdst_offset;
2922 RTE_ASSERT(extend == extend1);
2926 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2927 (size == NH_FLD_IPV6_ADDR_SIZE));
2930 (char *)(size_t)curr->qos_rule.key_iova +
2931 curr->ipaddr_rule.qos_ipdst_offset,
2933 memset((char *)(size_t)curr->qos_rule.key_iova +
2934 curr->ipaddr_rule.qos_ipdst_offset,
2938 (char *)(size_t)curr->qos_rule.mask_iova +
2939 curr->ipaddr_rule.qos_ipdst_offset,
2941 memset((char *)(size_t)curr->qos_rule.mask_iova +
2942 curr->ipaddr_rule.qos_ipdst_offset,
2945 curr->ipaddr_rule.qos_ipdst_offset = qos_ipdst_offset;
2948 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2949 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2950 (size == NH_FLD_IPV6_ADDR_SIZE));
2951 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2952 curr->ipaddr_rule.qos_ipsrc_offset,
2955 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2956 curr->ipaddr_rule.qos_ipsrc_offset,
2960 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2961 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2962 (size == NH_FLD_IPV6_ADDR_SIZE));
2963 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2964 curr->ipaddr_rule.qos_ipdst_offset,
2967 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2968 curr->ipaddr_rule.qos_ipdst_offset,
2974 curr->qos_real_key_size += extend;
2976 curr->qos_rule.key_size = FIXED_ENTRY_SIZE;
2978 dpaa2_flow_qos_entry_log("Start update", curr, qos_index);
2980 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
2981 priv->token, &curr->qos_rule,
2982 curr->tc_id, qos_index,
2985 DPAA2_PMD_ERR("Qos entry update failed.");
2989 if (curr->action != RTE_FLOW_ACTION_TYPE_QUEUE) {
2990 curr = LIST_NEXT(curr, next);
2994 dpaa2_flow_fs_entry_log("Before update", curr);
2997 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW,
2998 priv->token, curr->tc_id, &curr->fs_rule);
3000 DPAA2_PMD_ERR("FS entry remove failed.");
3004 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0 &&
3005 tc_id == curr->tc_id) {
3006 RTE_ASSERT(fs_ipsrc_offset >=
3007 curr->ipaddr_rule.fs_ipsrc_offset);
3008 extend1 = fs_ipsrc_offset -
3009 curr->ipaddr_rule.fs_ipsrc_offset;
3011 RTE_ASSERT(extend == extend1);
3016 (char *)(size_t)curr->fs_rule.key_iova +
3017 curr->ipaddr_rule.fs_ipsrc_offset,
3019 memset((char *)(size_t)curr->fs_rule.key_iova +
3020 curr->ipaddr_rule.fs_ipsrc_offset,
3024 (char *)(size_t)curr->fs_rule.mask_iova +
3025 curr->ipaddr_rule.fs_ipsrc_offset,
3027 memset((char *)(size_t)curr->fs_rule.mask_iova +
3028 curr->ipaddr_rule.fs_ipsrc_offset,
3031 curr->ipaddr_rule.fs_ipsrc_offset = fs_ipsrc_offset;
3034 if (curr->ipaddr_rule.fs_ipdst_offset >= 0 &&
3035 tc_id == curr->tc_id) {
3036 RTE_ASSERT(fs_ipdst_offset >=
3037 curr->ipaddr_rule.fs_ipdst_offset);
3038 extend1 = fs_ipdst_offset -
3039 curr->ipaddr_rule.fs_ipdst_offset;
3041 RTE_ASSERT(extend == extend1);
3046 (char *)(size_t)curr->fs_rule.key_iova +
3047 curr->ipaddr_rule.fs_ipdst_offset,
3049 memset((char *)(size_t)curr->fs_rule.key_iova +
3050 curr->ipaddr_rule.fs_ipdst_offset,
3054 (char *)(size_t)curr->fs_rule.mask_iova +
3055 curr->ipaddr_rule.fs_ipdst_offset,
3057 memset((char *)(size_t)curr->fs_rule.mask_iova +
3058 curr->ipaddr_rule.fs_ipdst_offset,
3061 curr->ipaddr_rule.fs_ipdst_offset = fs_ipdst_offset;
3064 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0) {
3065 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3066 curr->ipaddr_rule.fs_ipsrc_offset,
3069 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3070 curr->ipaddr_rule.fs_ipsrc_offset,
3074 if (curr->ipaddr_rule.fs_ipdst_offset >= 0) {
3075 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3076 curr->ipaddr_rule.fs_ipdst_offset,
3079 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3080 curr->ipaddr_rule.fs_ipdst_offset,
3086 curr->fs_real_key_size += extend;
3087 curr->fs_rule.key_size = FIXED_ENTRY_SIZE;
3089 dpaa2_flow_fs_entry_log("Start update", curr);
3091 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
3092 priv->token, curr->tc_id, curr->tc_index,
3093 &curr->fs_rule, &curr->action_cfg);
3095 DPAA2_PMD_ERR("FS entry update failed.");
3099 curr = LIST_NEXT(curr, next);
3106 dpaa2_flow_verify_attr(
3107 struct dpaa2_dev_priv *priv,
3108 const struct rte_flow_attr *attr)
3110 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3113 if (curr->tc_id == attr->group &&
3114 curr->tc_index == attr->priority) {
3116 "Flow with group %d and priority %d already exists.",
3117 attr->group, attr->priority);
3121 curr = LIST_NEXT(curr, next);
3128 dpaa2_flow_verify_action(
3129 struct dpaa2_dev_priv *priv,
3130 const struct rte_flow_attr *attr,
3131 const struct rte_flow_action actions[])
3133 int end_of_list = 0, i, j = 0;
3134 const struct rte_flow_action_queue *dest_queue;
3135 const struct rte_flow_action_rss *rss_conf;
3136 struct dpaa2_queue *rxq;
3138 while (!end_of_list) {
3139 switch (actions[j].type) {
3140 case RTE_FLOW_ACTION_TYPE_QUEUE:
3141 dest_queue = (const struct rte_flow_action_queue *)
3143 rxq = priv->rx_vq[dest_queue->index];
3144 if (attr->group != rxq->tc_index) {
3146 "RXQ[%d] does not belong to the group %d",
3147 dest_queue->index, attr->group);
3152 case RTE_FLOW_ACTION_TYPE_RSS:
3153 rss_conf = (const struct rte_flow_action_rss *)
3155 if (rss_conf->queue_num > priv->dist_queues) {
3157 "RSS number exceeds the distrbution size");
3160 for (i = 0; i < (int)rss_conf->queue_num; i++) {
3161 if (rss_conf->queue[i] >= priv->nb_rx_queues) {
3163 "RSS queue index exceeds the number of RXQs");
3166 rxq = priv->rx_vq[rss_conf->queue[i]];
3167 if (rxq->tc_index != attr->group) {
3169 "Queue/Group combination are not supported\n");
3175 case RTE_FLOW_ACTION_TYPE_END:
3179 DPAA2_PMD_ERR("Invalid action type");
3189 dpaa2_generic_flow_set(struct rte_flow *flow,
3190 struct rte_eth_dev *dev,
3191 const struct rte_flow_attr *attr,
3192 const struct rte_flow_item pattern[],
3193 const struct rte_flow_action actions[],
3194 struct rte_flow_error *error)
3196 const struct rte_flow_action_queue *dest_queue;
3197 const struct rte_flow_action_rss *rss_conf;
3198 int is_keycfg_configured = 0, end_of_list = 0;
3199 int ret = 0, i = 0, j = 0;
3200 struct dpni_rx_tc_dist_cfg tc_cfg;
3201 struct dpni_qos_tbl_cfg qos_cfg;
3202 struct dpni_fs_action_cfg action;
3203 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3204 struct dpaa2_queue *rxq;
3205 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3207 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3210 ret = dpaa2_flow_verify_attr(priv, attr);
3214 ret = dpaa2_flow_verify_action(priv, attr, actions);
3218 /* Parse pattern list to get the matching parameters */
3219 while (!end_of_list) {
3220 switch (pattern[i].type) {
3221 case RTE_FLOW_ITEM_TYPE_ETH:
3222 ret = dpaa2_configure_flow_eth(flow,
3223 dev, attr, &pattern[i], actions, error,
3224 &is_keycfg_configured);
3226 DPAA2_PMD_ERR("ETH flow configuration failed!");
3230 case RTE_FLOW_ITEM_TYPE_VLAN:
3231 ret = dpaa2_configure_flow_vlan(flow,
3232 dev, attr, &pattern[i], actions, error,
3233 &is_keycfg_configured);
3235 DPAA2_PMD_ERR("vLan flow configuration failed!");
3239 case RTE_FLOW_ITEM_TYPE_IPV4:
3240 case RTE_FLOW_ITEM_TYPE_IPV6:
3241 ret = dpaa2_configure_flow_generic_ip(flow,
3242 dev, attr, &pattern[i], actions, error,
3243 &is_keycfg_configured);
3245 DPAA2_PMD_ERR("IP flow configuration failed!");
3249 case RTE_FLOW_ITEM_TYPE_ICMP:
3250 ret = dpaa2_configure_flow_icmp(flow,
3251 dev, attr, &pattern[i], actions, error,
3252 &is_keycfg_configured);
3254 DPAA2_PMD_ERR("ICMP flow configuration failed!");
3258 case RTE_FLOW_ITEM_TYPE_UDP:
3259 ret = dpaa2_configure_flow_udp(flow,
3260 dev, attr, &pattern[i], actions, error,
3261 &is_keycfg_configured);
3263 DPAA2_PMD_ERR("UDP flow configuration failed!");
3267 case RTE_FLOW_ITEM_TYPE_TCP:
3268 ret = dpaa2_configure_flow_tcp(flow,
3269 dev, attr, &pattern[i], actions, error,
3270 &is_keycfg_configured);
3272 DPAA2_PMD_ERR("TCP flow configuration failed!");
3276 case RTE_FLOW_ITEM_TYPE_SCTP:
3277 ret = dpaa2_configure_flow_sctp(flow,
3278 dev, attr, &pattern[i], actions, error,
3279 &is_keycfg_configured);
3281 DPAA2_PMD_ERR("SCTP flow configuration failed!");
3285 case RTE_FLOW_ITEM_TYPE_GRE:
3286 ret = dpaa2_configure_flow_gre(flow,
3287 dev, attr, &pattern[i], actions, error,
3288 &is_keycfg_configured);
3290 DPAA2_PMD_ERR("GRE flow configuration failed!");
3294 case RTE_FLOW_ITEM_TYPE_END:
3296 break; /*End of List*/
3298 DPAA2_PMD_ERR("Invalid action type");
3305 /* Let's parse action on matching traffic */
3307 while (!end_of_list) {
3308 switch (actions[j].type) {
3309 case RTE_FLOW_ACTION_TYPE_QUEUE:
3311 (const struct rte_flow_action_queue *)(actions[j].conf);
3312 rxq = priv->rx_vq[dest_queue->index];
3313 flow->action = RTE_FLOW_ACTION_TYPE_QUEUE;
3314 memset(&action, 0, sizeof(struct dpni_fs_action_cfg));
3315 action.flow_id = rxq->flow_id;
3316 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3317 dpaa2_flow_qos_table_extracts_log(priv);
3318 if (dpkg_prepare_key_cfg(
3319 &priv->extract.qos_key_extract.dpkg,
3320 (uint8_t *)(size_t)priv->extract.qos_extract_param)
3323 "Unable to prepare extract parameters");
3327 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
3328 qos_cfg.discard_on_miss = true;
3329 qos_cfg.keep_entries = true;
3330 qos_cfg.key_cfg_iova =
3331 (size_t)priv->extract.qos_extract_param;
3332 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3333 priv->token, &qos_cfg);
3336 "Distribution cannot be configured.(%d)"
3341 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
3342 dpaa2_flow_fs_table_extracts_log(priv, flow->tc_id);
3343 if (dpkg_prepare_key_cfg(
3344 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3345 (uint8_t *)(size_t)priv->extract
3346 .tc_extract_param[flow->tc_id]) < 0) {
3348 "Unable to prepare extract parameters");
3352 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3353 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc;
3354 tc_cfg.dist_mode = DPNI_DIST_MODE_FS;
3355 tc_cfg.key_cfg_iova =
3356 (uint64_t)priv->extract.tc_extract_param[flow->tc_id];
3357 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3358 tc_cfg.fs_cfg.keep_entries = true;
3359 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3361 flow->tc_id, &tc_cfg);
3364 "Distribution cannot be configured.(%d)"
3369 /* Configure QoS table first */
3371 qos_index = flow->tc_id * priv->fs_entries +
3374 if (qos_index >= priv->qos_entries) {
3375 DPAA2_PMD_ERR("QoS table with %d entries full",
3379 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3380 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR) {
3381 if (flow->ipaddr_rule.qos_ipdst_offset >=
3382 flow->ipaddr_rule.qos_ipsrc_offset) {
3383 flow->qos_real_key_size =
3384 flow->ipaddr_rule.qos_ipdst_offset +
3385 NH_FLD_IPV4_ADDR_SIZE;
3387 flow->qos_real_key_size =
3388 flow->ipaddr_rule.qos_ipsrc_offset +
3389 NH_FLD_IPV4_ADDR_SIZE;
3391 } else if (flow->ipaddr_rule.ipaddr_type ==
3393 if (flow->ipaddr_rule.qos_ipdst_offset >=
3394 flow->ipaddr_rule.qos_ipsrc_offset) {
3395 flow->qos_real_key_size =
3396 flow->ipaddr_rule.qos_ipdst_offset +
3397 NH_FLD_IPV6_ADDR_SIZE;
3399 flow->qos_real_key_size =
3400 flow->ipaddr_rule.qos_ipsrc_offset +
3401 NH_FLD_IPV6_ADDR_SIZE;
3405 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3407 dpaa2_flow_qos_entry_log("Start add", flow, qos_index);
3409 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
3410 priv->token, &flow->qos_rule,
3411 flow->tc_id, qos_index,
3415 "Error in addnig entry to QoS table(%d)", ret);
3419 /* Then Configure FS table */
3420 if (flow->tc_index >= priv->fs_entries) {
3421 DPAA2_PMD_ERR("FS table with %d entries full",
3426 flow->fs_real_key_size =
3427 priv->extract.tc_key_extract[flow->tc_id]
3428 .key_info.key_total_size;
3430 if (flow->ipaddr_rule.ipaddr_type ==
3432 if (flow->ipaddr_rule.fs_ipdst_offset >=
3433 flow->ipaddr_rule.fs_ipsrc_offset) {
3434 flow->fs_real_key_size =
3435 flow->ipaddr_rule.fs_ipdst_offset +
3436 NH_FLD_IPV4_ADDR_SIZE;
3438 flow->fs_real_key_size =
3439 flow->ipaddr_rule.fs_ipsrc_offset +
3440 NH_FLD_IPV4_ADDR_SIZE;
3442 } else if (flow->ipaddr_rule.ipaddr_type ==
3444 if (flow->ipaddr_rule.fs_ipdst_offset >=
3445 flow->ipaddr_rule.fs_ipsrc_offset) {
3446 flow->fs_real_key_size =
3447 flow->ipaddr_rule.fs_ipdst_offset +
3448 NH_FLD_IPV6_ADDR_SIZE;
3450 flow->fs_real_key_size =
3451 flow->ipaddr_rule.fs_ipsrc_offset +
3452 NH_FLD_IPV6_ADDR_SIZE;
3456 flow->fs_rule.key_size = FIXED_ENTRY_SIZE;
3458 dpaa2_flow_fs_entry_log("Start add", flow);
3460 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3461 flow->tc_id, flow->tc_index,
3462 &flow->fs_rule, &action);
3465 "Error in adding entry to FS table(%d)", ret);
3468 memcpy(&flow->action_cfg, &action,
3469 sizeof(struct dpni_fs_action_cfg));
3471 case RTE_FLOW_ACTION_TYPE_RSS:
3472 rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf);
3474 flow->action = RTE_FLOW_ACTION_TYPE_RSS;
3475 ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
3476 &priv->extract.tc_key_extract[flow->tc_id].dpkg);
3479 "unable to set flow distribution.please check queue config\n");
3483 /* Allocate DMA'ble memory to write the rules */
3484 param = (size_t)rte_malloc(NULL, 256, 64);
3486 DPAA2_PMD_ERR("Memory allocation failure\n");
3490 if (dpkg_prepare_key_cfg(
3491 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3492 (uint8_t *)param) < 0) {
3494 "Unable to prepare extract parameters");
3495 rte_free((void *)param);
3499 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3500 tc_cfg.dist_size = rss_conf->queue_num;
3501 tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
3502 tc_cfg.key_cfg_iova = (size_t)param;
3503 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3505 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3506 priv->token, flow->tc_id,
3510 "Distribution cannot be configured: %d\n", ret);
3511 rte_free((void *)param);
3515 rte_free((void *)param);
3516 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3517 if (dpkg_prepare_key_cfg(
3518 &priv->extract.qos_key_extract.dpkg,
3519 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3521 "Unable to prepare extract parameters");
3525 sizeof(struct dpni_qos_tbl_cfg));
3526 qos_cfg.discard_on_miss = true;
3527 qos_cfg.keep_entries = true;
3528 qos_cfg.key_cfg_iova =
3529 (size_t)priv->extract.qos_extract_param;
3530 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3531 priv->token, &qos_cfg);
3534 "Distribution can't be configured %d\n",
3540 /* Add Rule into QoS table */
3541 qos_index = flow->tc_id * priv->fs_entries +
3543 if (qos_index >= priv->qos_entries) {
3544 DPAA2_PMD_ERR("QoS table with %d entries full",
3549 flow->qos_real_key_size =
3550 priv->extract.qos_key_extract.key_info.key_total_size;
3551 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3552 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3553 &flow->qos_rule, flow->tc_id,
3557 "Error in entry addition in QoS table(%d)",
3562 case RTE_FLOW_ACTION_TYPE_END:
3566 DPAA2_PMD_ERR("Invalid action type");
3574 if (is_keycfg_configured &
3575 (DPAA2_QOS_TABLE_RECONFIGURE |
3576 DPAA2_FS_TABLE_RECONFIGURE)) {
3577 ret = dpaa2_flow_entry_update(priv, flow->tc_id);
3579 DPAA2_PMD_ERR("Flow entry update failed.");
3584 /* New rules are inserted. */
3586 LIST_INSERT_HEAD(&priv->flows, flow, next);
3588 while (LIST_NEXT(curr, next))
3589 curr = LIST_NEXT(curr, next);
3590 LIST_INSERT_AFTER(curr, flow, next);
3597 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
3598 const struct rte_flow_attr *attr)
3602 if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
3603 DPAA2_PMD_ERR("Priority group is out of range\n");
3606 if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
3607 DPAA2_PMD_ERR("Priority within the group is out of range\n");
3610 if (unlikely(attr->egress)) {
3612 "Flow configuration is not supported on egress side\n");
3615 if (unlikely(!attr->ingress)) {
3616 DPAA2_PMD_ERR("Ingress flag must be configured\n");
3623 dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
3625 unsigned int i, j, is_found = 0;
3628 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3629 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) {
3630 if (dpaa2_supported_pattern_type[i]
3631 == pattern[j].type) {
3641 /* Lets verify other combinations of given pattern rules */
3642 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3643 if (!pattern[j].spec) {
3653 dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
3655 unsigned int i, j, is_found = 0;
3658 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3659 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
3660 if (dpaa2_supported_action_type[i] == actions[j].type) {
3670 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3671 if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
3679 int dpaa2_flow_validate(struct rte_eth_dev *dev,
3680 const struct rte_flow_attr *flow_attr,
3681 const struct rte_flow_item pattern[],
3682 const struct rte_flow_action actions[],
3683 struct rte_flow_error *error)
3685 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3686 struct dpni_attr dpni_attr;
3687 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3688 uint16_t token = priv->token;
3691 memset(&dpni_attr, 0, sizeof(struct dpni_attr));
3692 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
3695 "Failure to get dpni@%p attribute, err code %d\n",
3697 rte_flow_error_set(error, EPERM,
3698 RTE_FLOW_ERROR_TYPE_ATTR,
3699 flow_attr, "invalid");
3703 /* Verify input attributes */
3704 ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
3707 "Invalid attributes are given\n");
3708 rte_flow_error_set(error, EPERM,
3709 RTE_FLOW_ERROR_TYPE_ATTR,
3710 flow_attr, "invalid");
3711 goto not_valid_params;
3713 /* Verify input pattern list */
3714 ret = dpaa2_dev_verify_patterns(pattern);
3717 "Invalid pattern list is given\n");
3718 rte_flow_error_set(error, EPERM,
3719 RTE_FLOW_ERROR_TYPE_ITEM,
3720 pattern, "invalid");
3721 goto not_valid_params;
3723 /* Verify input action list */
3724 ret = dpaa2_dev_verify_actions(actions);
3727 "Invalid action list is given\n");
3728 rte_flow_error_set(error, EPERM,
3729 RTE_FLOW_ERROR_TYPE_ACTION,
3730 actions, "invalid");
3731 goto not_valid_params;
3738 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev,
3739 const struct rte_flow_attr *attr,
3740 const struct rte_flow_item pattern[],
3741 const struct rte_flow_action actions[],
3742 struct rte_flow_error *error)
3744 struct rte_flow *flow = NULL;
3745 size_t key_iova = 0, mask_iova = 0;
3748 dpaa2_flow_control_log =
3749 getenv("DPAA2_FLOW_CONTROL_LOG");
3751 flow = rte_zmalloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE);
3753 DPAA2_PMD_ERR("Failure to allocate memory for flow");
3756 /* Allocate DMA'ble memory to write the rules */
3757 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3760 "Memory allocation failure for rule configuration\n");
3763 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3766 "Memory allocation failure for rule configuration\n");
3770 flow->qos_rule.key_iova = key_iova;
3771 flow->qos_rule.mask_iova = mask_iova;
3773 /* Allocate DMA'ble memory to write the rules */
3774 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3777 "Memory allocation failure for rule configuration\n");
3780 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3783 "Memory allocation failure for rule configuration\n");
3787 flow->fs_rule.key_iova = key_iova;
3788 flow->fs_rule.mask_iova = mask_iova;
3790 flow->ipaddr_rule.ipaddr_type = FLOW_NONE_IPADDR;
3791 flow->ipaddr_rule.qos_ipsrc_offset =
3792 IP_ADDRESS_OFFSET_INVALID;
3793 flow->ipaddr_rule.qos_ipdst_offset =
3794 IP_ADDRESS_OFFSET_INVALID;
3795 flow->ipaddr_rule.fs_ipsrc_offset =
3796 IP_ADDRESS_OFFSET_INVALID;
3797 flow->ipaddr_rule.fs_ipdst_offset =
3798 IP_ADDRESS_OFFSET_INVALID;
3800 switch (dpaa2_filter_type) {
3801 case RTE_ETH_FILTER_GENERIC:
3802 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern,
3805 if (error->type > RTE_FLOW_ERROR_TYPE_ACTION)
3806 rte_flow_error_set(error, EPERM,
3807 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3810 "Failure to create flow, return code (%d)", ret);
3811 goto creation_error;
3815 DPAA2_PMD_ERR("Filter type (%d) not supported",
3822 rte_flow_error_set(error, EPERM,
3823 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3824 NULL, "memory alloc");
3826 rte_free((void *)flow);
3827 rte_free((void *)key_iova);
3828 rte_free((void *)mask_iova);
3834 int dpaa2_flow_destroy(struct rte_eth_dev *dev,
3835 struct rte_flow *flow,
3836 struct rte_flow_error *error)
3839 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3840 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3842 switch (flow->action) {
3843 case RTE_FLOW_ACTION_TYPE_QUEUE:
3844 /* Remove entry from QoS table first */
3845 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3849 "Error in adding entry to QoS table(%d)", ret);
3853 /* Then remove entry from FS table */
3854 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3855 flow->tc_id, &flow->fs_rule);
3858 "Error in entry addition in FS table(%d)", ret);
3862 case RTE_FLOW_ACTION_TYPE_RSS:
3863 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3867 "Error in entry addition in QoS table(%d)", ret);
3873 "Action type (%d) is not supported", flow->action);
3878 LIST_REMOVE(flow, next);
3879 rte_free((void *)(size_t)flow->qos_rule.key_iova);
3880 rte_free((void *)(size_t)flow->qos_rule.mask_iova);
3881 rte_free((void *)(size_t)flow->fs_rule.key_iova);
3882 rte_free((void *)(size_t)flow->fs_rule.mask_iova);
3883 /* Now free the flow */
3888 rte_flow_error_set(error, EPERM,
3889 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3895 * Destroy user-configured flow rules.
3897 * This function skips internal flows rules.
3899 * @see rte_flow_flush()
3903 dpaa2_flow_flush(struct rte_eth_dev *dev,
3904 struct rte_flow_error *error)
3906 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3907 struct rte_flow *flow = LIST_FIRST(&priv->flows);
3910 struct rte_flow *next = LIST_NEXT(flow, next);
3912 dpaa2_flow_destroy(dev, flow, error);
3919 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
3920 struct rte_flow *flow __rte_unused,
3921 const struct rte_flow_action *actions __rte_unused,
3922 void *data __rte_unused,
3923 struct rte_flow_error *error __rte_unused)
3929 * Clean up all flow rules.
3931 * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
3932 * rules regardless of whether they are internal or user-configured.
3935 * Pointer to private structure.
3938 dpaa2_flow_clean(struct rte_eth_dev *dev)
3940 struct rte_flow *flow;
3941 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3943 while ((flow = LIST_FIRST(&priv->flows)))
3944 dpaa2_flow_destroy(dev, flow, NULL);
3947 const struct rte_flow_ops dpaa2_flow_ops = {
3948 .create = dpaa2_flow_create,
3949 .validate = dpaa2_flow_validate,
3950 .destroy = dpaa2_flow_destroy,
3951 .flush = dpaa2_flow_flush,
3952 .query = dpaa2_flow_query,