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 if (priv->num_rx_tc > 1) {
2876 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
2877 priv->token, &curr->qos_rule);
2879 DPAA2_PMD_ERR("Qos entry remove failed.");
2886 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2887 RTE_ASSERT(qos_ipsrc_offset >=
2888 curr->ipaddr_rule.qos_ipsrc_offset);
2889 extend1 = qos_ipsrc_offset -
2890 curr->ipaddr_rule.qos_ipsrc_offset;
2892 RTE_ASSERT(extend == extend1);
2896 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2897 (size == NH_FLD_IPV6_ADDR_SIZE));
2900 (char *)(size_t)curr->qos_rule.key_iova +
2901 curr->ipaddr_rule.qos_ipsrc_offset,
2903 memset((char *)(size_t)curr->qos_rule.key_iova +
2904 curr->ipaddr_rule.qos_ipsrc_offset,
2908 (char *)(size_t)curr->qos_rule.mask_iova +
2909 curr->ipaddr_rule.qos_ipsrc_offset,
2911 memset((char *)(size_t)curr->qos_rule.mask_iova +
2912 curr->ipaddr_rule.qos_ipsrc_offset,
2915 curr->ipaddr_rule.qos_ipsrc_offset = qos_ipsrc_offset;
2918 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2919 RTE_ASSERT(qos_ipdst_offset >=
2920 curr->ipaddr_rule.qos_ipdst_offset);
2921 extend1 = qos_ipdst_offset -
2922 curr->ipaddr_rule.qos_ipdst_offset;
2924 RTE_ASSERT(extend == extend1);
2928 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2929 (size == NH_FLD_IPV6_ADDR_SIZE));
2932 (char *)(size_t)curr->qos_rule.key_iova +
2933 curr->ipaddr_rule.qos_ipdst_offset,
2935 memset((char *)(size_t)curr->qos_rule.key_iova +
2936 curr->ipaddr_rule.qos_ipdst_offset,
2940 (char *)(size_t)curr->qos_rule.mask_iova +
2941 curr->ipaddr_rule.qos_ipdst_offset,
2943 memset((char *)(size_t)curr->qos_rule.mask_iova +
2944 curr->ipaddr_rule.qos_ipdst_offset,
2947 curr->ipaddr_rule.qos_ipdst_offset = qos_ipdst_offset;
2950 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2951 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2952 (size == NH_FLD_IPV6_ADDR_SIZE));
2953 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2954 curr->ipaddr_rule.qos_ipsrc_offset,
2957 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2958 curr->ipaddr_rule.qos_ipsrc_offset,
2962 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2963 RTE_ASSERT((size == NH_FLD_IPV4_ADDR_SIZE) ||
2964 (size == NH_FLD_IPV6_ADDR_SIZE));
2965 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2966 curr->ipaddr_rule.qos_ipdst_offset,
2969 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2970 curr->ipaddr_rule.qos_ipdst_offset,
2976 curr->qos_real_key_size += extend;
2978 curr->qos_rule.key_size = FIXED_ENTRY_SIZE;
2980 dpaa2_flow_qos_entry_log("Start update", curr, qos_index);
2982 if (priv->num_rx_tc > 1) {
2983 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
2984 priv->token, &curr->qos_rule,
2985 curr->tc_id, qos_index,
2988 DPAA2_PMD_ERR("Qos entry update failed.");
2993 if (curr->action != RTE_FLOW_ACTION_TYPE_QUEUE) {
2994 curr = LIST_NEXT(curr, next);
2998 dpaa2_flow_fs_entry_log("Before update", curr);
3001 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW,
3002 priv->token, curr->tc_id, &curr->fs_rule);
3004 DPAA2_PMD_ERR("FS entry remove failed.");
3008 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0 &&
3009 tc_id == curr->tc_id) {
3010 RTE_ASSERT(fs_ipsrc_offset >=
3011 curr->ipaddr_rule.fs_ipsrc_offset);
3012 extend1 = fs_ipsrc_offset -
3013 curr->ipaddr_rule.fs_ipsrc_offset;
3015 RTE_ASSERT(extend == extend1);
3020 (char *)(size_t)curr->fs_rule.key_iova +
3021 curr->ipaddr_rule.fs_ipsrc_offset,
3023 memset((char *)(size_t)curr->fs_rule.key_iova +
3024 curr->ipaddr_rule.fs_ipsrc_offset,
3028 (char *)(size_t)curr->fs_rule.mask_iova +
3029 curr->ipaddr_rule.fs_ipsrc_offset,
3031 memset((char *)(size_t)curr->fs_rule.mask_iova +
3032 curr->ipaddr_rule.fs_ipsrc_offset,
3035 curr->ipaddr_rule.fs_ipsrc_offset = fs_ipsrc_offset;
3038 if (curr->ipaddr_rule.fs_ipdst_offset >= 0 &&
3039 tc_id == curr->tc_id) {
3040 RTE_ASSERT(fs_ipdst_offset >=
3041 curr->ipaddr_rule.fs_ipdst_offset);
3042 extend1 = fs_ipdst_offset -
3043 curr->ipaddr_rule.fs_ipdst_offset;
3045 RTE_ASSERT(extend == extend1);
3050 (char *)(size_t)curr->fs_rule.key_iova +
3051 curr->ipaddr_rule.fs_ipdst_offset,
3053 memset((char *)(size_t)curr->fs_rule.key_iova +
3054 curr->ipaddr_rule.fs_ipdst_offset,
3058 (char *)(size_t)curr->fs_rule.mask_iova +
3059 curr->ipaddr_rule.fs_ipdst_offset,
3061 memset((char *)(size_t)curr->fs_rule.mask_iova +
3062 curr->ipaddr_rule.fs_ipdst_offset,
3065 curr->ipaddr_rule.fs_ipdst_offset = fs_ipdst_offset;
3068 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0) {
3069 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3070 curr->ipaddr_rule.fs_ipsrc_offset,
3073 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3074 curr->ipaddr_rule.fs_ipsrc_offset,
3078 if (curr->ipaddr_rule.fs_ipdst_offset >= 0) {
3079 memcpy((char *)(size_t)curr->fs_rule.key_iova +
3080 curr->ipaddr_rule.fs_ipdst_offset,
3083 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
3084 curr->ipaddr_rule.fs_ipdst_offset,
3090 curr->fs_real_key_size += extend;
3091 curr->fs_rule.key_size = FIXED_ENTRY_SIZE;
3093 dpaa2_flow_fs_entry_log("Start update", curr);
3095 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
3096 priv->token, curr->tc_id, curr->tc_index,
3097 &curr->fs_rule, &curr->action_cfg);
3099 DPAA2_PMD_ERR("FS entry update failed.");
3103 curr = LIST_NEXT(curr, next);
3110 dpaa2_flow_verify_attr(
3111 struct dpaa2_dev_priv *priv,
3112 const struct rte_flow_attr *attr)
3114 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3117 if (curr->tc_id == attr->group &&
3118 curr->tc_index == attr->priority) {
3120 "Flow with group %d and priority %d already exists.",
3121 attr->group, attr->priority);
3125 curr = LIST_NEXT(curr, next);
3132 dpaa2_flow_verify_action(
3133 struct dpaa2_dev_priv *priv,
3134 const struct rte_flow_attr *attr,
3135 const struct rte_flow_action actions[])
3137 int end_of_list = 0, i, j = 0;
3138 const struct rte_flow_action_queue *dest_queue;
3139 const struct rte_flow_action_rss *rss_conf;
3140 struct dpaa2_queue *rxq;
3142 while (!end_of_list) {
3143 switch (actions[j].type) {
3144 case RTE_FLOW_ACTION_TYPE_QUEUE:
3145 dest_queue = (const struct rte_flow_action_queue *)
3147 rxq = priv->rx_vq[dest_queue->index];
3148 if (attr->group != rxq->tc_index) {
3150 "RXQ[%d] does not belong to the group %d",
3151 dest_queue->index, attr->group);
3156 case RTE_FLOW_ACTION_TYPE_RSS:
3157 rss_conf = (const struct rte_flow_action_rss *)
3159 if (rss_conf->queue_num > priv->dist_queues) {
3161 "RSS number exceeds the distrbution size");
3164 for (i = 0; i < (int)rss_conf->queue_num; i++) {
3165 if (rss_conf->queue[i] >= priv->nb_rx_queues) {
3167 "RSS queue index exceeds the number of RXQs");
3170 rxq = priv->rx_vq[rss_conf->queue[i]];
3171 if (rxq->tc_index != attr->group) {
3173 "Queue/Group combination are not supported\n");
3179 case RTE_FLOW_ACTION_TYPE_END:
3183 DPAA2_PMD_ERR("Invalid action type");
3193 dpaa2_generic_flow_set(struct rte_flow *flow,
3194 struct rte_eth_dev *dev,
3195 const struct rte_flow_attr *attr,
3196 const struct rte_flow_item pattern[],
3197 const struct rte_flow_action actions[],
3198 struct rte_flow_error *error)
3200 const struct rte_flow_action_queue *dest_queue;
3201 const struct rte_flow_action_rss *rss_conf;
3202 int is_keycfg_configured = 0, end_of_list = 0;
3203 int ret = 0, i = 0, j = 0;
3204 struct dpni_rx_tc_dist_cfg tc_cfg;
3205 struct dpni_qos_tbl_cfg qos_cfg;
3206 struct dpni_fs_action_cfg action;
3207 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3208 struct dpaa2_queue *rxq;
3209 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3211 struct rte_flow *curr = LIST_FIRST(&priv->flows);
3214 ret = dpaa2_flow_verify_attr(priv, attr);
3218 ret = dpaa2_flow_verify_action(priv, attr, actions);
3222 /* Parse pattern list to get the matching parameters */
3223 while (!end_of_list) {
3224 switch (pattern[i].type) {
3225 case RTE_FLOW_ITEM_TYPE_ETH:
3226 ret = dpaa2_configure_flow_eth(flow,
3227 dev, attr, &pattern[i], actions, error,
3228 &is_keycfg_configured);
3230 DPAA2_PMD_ERR("ETH flow configuration failed!");
3234 case RTE_FLOW_ITEM_TYPE_VLAN:
3235 ret = dpaa2_configure_flow_vlan(flow,
3236 dev, attr, &pattern[i], actions, error,
3237 &is_keycfg_configured);
3239 DPAA2_PMD_ERR("vLan flow configuration failed!");
3243 case RTE_FLOW_ITEM_TYPE_IPV4:
3244 case RTE_FLOW_ITEM_TYPE_IPV6:
3245 ret = dpaa2_configure_flow_generic_ip(flow,
3246 dev, attr, &pattern[i], actions, error,
3247 &is_keycfg_configured);
3249 DPAA2_PMD_ERR("IP flow configuration failed!");
3253 case RTE_FLOW_ITEM_TYPE_ICMP:
3254 ret = dpaa2_configure_flow_icmp(flow,
3255 dev, attr, &pattern[i], actions, error,
3256 &is_keycfg_configured);
3258 DPAA2_PMD_ERR("ICMP flow configuration failed!");
3262 case RTE_FLOW_ITEM_TYPE_UDP:
3263 ret = dpaa2_configure_flow_udp(flow,
3264 dev, attr, &pattern[i], actions, error,
3265 &is_keycfg_configured);
3267 DPAA2_PMD_ERR("UDP flow configuration failed!");
3271 case RTE_FLOW_ITEM_TYPE_TCP:
3272 ret = dpaa2_configure_flow_tcp(flow,
3273 dev, attr, &pattern[i], actions, error,
3274 &is_keycfg_configured);
3276 DPAA2_PMD_ERR("TCP flow configuration failed!");
3280 case RTE_FLOW_ITEM_TYPE_SCTP:
3281 ret = dpaa2_configure_flow_sctp(flow,
3282 dev, attr, &pattern[i], actions, error,
3283 &is_keycfg_configured);
3285 DPAA2_PMD_ERR("SCTP flow configuration failed!");
3289 case RTE_FLOW_ITEM_TYPE_GRE:
3290 ret = dpaa2_configure_flow_gre(flow,
3291 dev, attr, &pattern[i], actions, error,
3292 &is_keycfg_configured);
3294 DPAA2_PMD_ERR("GRE flow configuration failed!");
3298 case RTE_FLOW_ITEM_TYPE_END:
3300 break; /*End of List*/
3302 DPAA2_PMD_ERR("Invalid action type");
3309 /* Let's parse action on matching traffic */
3311 while (!end_of_list) {
3312 switch (actions[j].type) {
3313 case RTE_FLOW_ACTION_TYPE_QUEUE:
3315 (const struct rte_flow_action_queue *)(actions[j].conf);
3316 rxq = priv->rx_vq[dest_queue->index];
3317 flow->action = RTE_FLOW_ACTION_TYPE_QUEUE;
3318 memset(&action, 0, sizeof(struct dpni_fs_action_cfg));
3319 action.flow_id = rxq->flow_id;
3321 /* Configure FS table first*/
3322 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
3323 dpaa2_flow_fs_table_extracts_log(priv, flow->tc_id);
3324 if (dpkg_prepare_key_cfg(
3325 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3326 (uint8_t *)(size_t)priv->extract
3327 .tc_extract_param[flow->tc_id]) < 0) {
3329 "Unable to prepare extract parameters");
3333 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3334 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc;
3335 tc_cfg.dist_mode = DPNI_DIST_MODE_FS;
3336 tc_cfg.key_cfg_iova =
3337 (uint64_t)priv->extract.tc_extract_param[flow->tc_id];
3338 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3339 tc_cfg.fs_cfg.keep_entries = true;
3340 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3342 flow->tc_id, &tc_cfg);
3345 "Distribution cannot be configured.(%d)"
3351 /* Configure QoS table then.*/
3352 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3353 dpaa2_flow_qos_table_extracts_log(priv);
3354 if (dpkg_prepare_key_cfg(
3355 &priv->extract.qos_key_extract.dpkg,
3356 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3358 "Unable to prepare extract parameters");
3362 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
3363 qos_cfg.discard_on_miss = false;
3364 qos_cfg.default_tc = 0;
3365 qos_cfg.keep_entries = true;
3366 qos_cfg.key_cfg_iova =
3367 (size_t)priv->extract.qos_extract_param;
3368 /* QoS table is effecitive for multiple TCs.*/
3369 if (priv->num_rx_tc > 1) {
3370 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3371 priv->token, &qos_cfg);
3374 "RSS QoS table can not be configured(%d)\n",
3381 flow->qos_real_key_size = priv->extract
3382 .qos_key_extract.key_info.key_total_size;
3383 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR) {
3384 if (flow->ipaddr_rule.qos_ipdst_offset >=
3385 flow->ipaddr_rule.qos_ipsrc_offset) {
3386 flow->qos_real_key_size =
3387 flow->ipaddr_rule.qos_ipdst_offset +
3388 NH_FLD_IPV4_ADDR_SIZE;
3390 flow->qos_real_key_size =
3391 flow->ipaddr_rule.qos_ipsrc_offset +
3392 NH_FLD_IPV4_ADDR_SIZE;
3394 } else if (flow->ipaddr_rule.ipaddr_type ==
3396 if (flow->ipaddr_rule.qos_ipdst_offset >=
3397 flow->ipaddr_rule.qos_ipsrc_offset) {
3398 flow->qos_real_key_size =
3399 flow->ipaddr_rule.qos_ipdst_offset +
3400 NH_FLD_IPV6_ADDR_SIZE;
3402 flow->qos_real_key_size =
3403 flow->ipaddr_rule.qos_ipsrc_offset +
3404 NH_FLD_IPV6_ADDR_SIZE;
3408 /* QoS entry added is only effective for multiple TCs.*/
3409 if (priv->num_rx_tc > 1) {
3410 qos_index = flow->tc_id * priv->fs_entries +
3412 if (qos_index >= priv->qos_entries) {
3413 DPAA2_PMD_ERR("QoS table with %d entries full",
3417 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3419 dpaa2_flow_qos_entry_log("Start add", flow, qos_index);
3421 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
3422 priv->token, &flow->qos_rule,
3423 flow->tc_id, qos_index,
3427 "Error in addnig entry to QoS table(%d)", ret);
3432 if (flow->tc_index >= priv->fs_entries) {
3433 DPAA2_PMD_ERR("FS table with %d entries full",
3438 flow->fs_real_key_size =
3439 priv->extract.tc_key_extract[flow->tc_id]
3440 .key_info.key_total_size;
3442 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_IPV4_ADDR_SIZE;
3450 flow->fs_real_key_size =
3451 flow->ipaddr_rule.fs_ipsrc_offset +
3452 NH_FLD_IPV4_ADDR_SIZE;
3454 } else if (flow->ipaddr_rule.ipaddr_type ==
3456 if (flow->ipaddr_rule.fs_ipdst_offset >=
3457 flow->ipaddr_rule.fs_ipsrc_offset) {
3458 flow->fs_real_key_size =
3459 flow->ipaddr_rule.fs_ipdst_offset +
3460 NH_FLD_IPV6_ADDR_SIZE;
3462 flow->fs_real_key_size =
3463 flow->ipaddr_rule.fs_ipsrc_offset +
3464 NH_FLD_IPV6_ADDR_SIZE;
3468 flow->fs_rule.key_size = FIXED_ENTRY_SIZE;
3470 dpaa2_flow_fs_entry_log("Start add", flow);
3472 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3473 flow->tc_id, flow->tc_index,
3474 &flow->fs_rule, &action);
3477 "Error in adding entry to FS table(%d)", ret);
3480 memcpy(&flow->action_cfg, &action,
3481 sizeof(struct dpni_fs_action_cfg));
3483 case RTE_FLOW_ACTION_TYPE_RSS:
3484 rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf);
3486 flow->action = RTE_FLOW_ACTION_TYPE_RSS;
3487 ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
3488 &priv->extract.tc_key_extract[flow->tc_id].dpkg);
3491 "unable to set flow distribution.please check queue config\n");
3495 /* Allocate DMA'ble memory to write the rules */
3496 param = (size_t)rte_malloc(NULL, 256, 64);
3498 DPAA2_PMD_ERR("Memory allocation failure\n");
3502 if (dpkg_prepare_key_cfg(
3503 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3504 (uint8_t *)param) < 0) {
3506 "Unable to prepare extract parameters");
3507 rte_free((void *)param);
3511 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3512 tc_cfg.dist_size = rss_conf->queue_num;
3513 tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
3514 tc_cfg.key_cfg_iova = (size_t)param;
3515 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3517 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3518 priv->token, flow->tc_id,
3522 "RSS FS table cannot be configured: %d\n",
3524 rte_free((void *)param);
3528 rte_free((void *)param);
3529 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3530 if (dpkg_prepare_key_cfg(
3531 &priv->extract.qos_key_extract.dpkg,
3532 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3534 "Unable to prepare extract parameters");
3538 sizeof(struct dpni_qos_tbl_cfg));
3539 qos_cfg.discard_on_miss = true;
3540 qos_cfg.keep_entries = true;
3541 qos_cfg.key_cfg_iova =
3542 (size_t)priv->extract.qos_extract_param;
3543 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3544 priv->token, &qos_cfg);
3547 "Distribution can't be configured %d\n",
3553 /* Add Rule into QoS table */
3554 qos_index = flow->tc_id * priv->fs_entries +
3556 if (qos_index >= priv->qos_entries) {
3557 DPAA2_PMD_ERR("QoS table with %d entries full",
3562 flow->qos_real_key_size =
3563 priv->extract.qos_key_extract.key_info.key_total_size;
3564 flow->qos_rule.key_size = FIXED_ENTRY_SIZE;
3565 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3566 &flow->qos_rule, flow->tc_id,
3570 "Error in entry addition in QoS table(%d)",
3575 case RTE_FLOW_ACTION_TYPE_END:
3579 DPAA2_PMD_ERR("Invalid action type");
3587 if (is_keycfg_configured &
3588 (DPAA2_QOS_TABLE_RECONFIGURE |
3589 DPAA2_FS_TABLE_RECONFIGURE)) {
3590 ret = dpaa2_flow_entry_update(priv, flow->tc_id);
3592 DPAA2_PMD_ERR("Flow entry update failed.");
3597 /* New rules are inserted. */
3599 LIST_INSERT_HEAD(&priv->flows, flow, next);
3601 while (LIST_NEXT(curr, next))
3602 curr = LIST_NEXT(curr, next);
3603 LIST_INSERT_AFTER(curr, flow, next);
3610 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
3611 const struct rte_flow_attr *attr)
3615 if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
3616 DPAA2_PMD_ERR("Priority group is out of range\n");
3619 if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
3620 DPAA2_PMD_ERR("Priority within the group is out of range\n");
3623 if (unlikely(attr->egress)) {
3625 "Flow configuration is not supported on egress side\n");
3628 if (unlikely(!attr->ingress)) {
3629 DPAA2_PMD_ERR("Ingress flag must be configured\n");
3636 dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
3638 unsigned int i, j, is_found = 0;
3641 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3642 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) {
3643 if (dpaa2_supported_pattern_type[i]
3644 == pattern[j].type) {
3654 /* Lets verify other combinations of given pattern rules */
3655 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3656 if (!pattern[j].spec) {
3666 dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
3668 unsigned int i, j, is_found = 0;
3671 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3672 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
3673 if (dpaa2_supported_action_type[i] == actions[j].type) {
3683 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3684 if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
3692 int dpaa2_flow_validate(struct rte_eth_dev *dev,
3693 const struct rte_flow_attr *flow_attr,
3694 const struct rte_flow_item pattern[],
3695 const struct rte_flow_action actions[],
3696 struct rte_flow_error *error)
3698 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3699 struct dpni_attr dpni_attr;
3700 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3701 uint16_t token = priv->token;
3704 memset(&dpni_attr, 0, sizeof(struct dpni_attr));
3705 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
3708 "Failure to get dpni@%p attribute, err code %d\n",
3710 rte_flow_error_set(error, EPERM,
3711 RTE_FLOW_ERROR_TYPE_ATTR,
3712 flow_attr, "invalid");
3716 /* Verify input attributes */
3717 ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
3720 "Invalid attributes are given\n");
3721 rte_flow_error_set(error, EPERM,
3722 RTE_FLOW_ERROR_TYPE_ATTR,
3723 flow_attr, "invalid");
3724 goto not_valid_params;
3726 /* Verify input pattern list */
3727 ret = dpaa2_dev_verify_patterns(pattern);
3730 "Invalid pattern list is given\n");
3731 rte_flow_error_set(error, EPERM,
3732 RTE_FLOW_ERROR_TYPE_ITEM,
3733 pattern, "invalid");
3734 goto not_valid_params;
3736 /* Verify input action list */
3737 ret = dpaa2_dev_verify_actions(actions);
3740 "Invalid action list is given\n");
3741 rte_flow_error_set(error, EPERM,
3742 RTE_FLOW_ERROR_TYPE_ACTION,
3743 actions, "invalid");
3744 goto not_valid_params;
3751 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev,
3752 const struct rte_flow_attr *attr,
3753 const struct rte_flow_item pattern[],
3754 const struct rte_flow_action actions[],
3755 struct rte_flow_error *error)
3757 struct rte_flow *flow = NULL;
3758 size_t key_iova = 0, mask_iova = 0;
3761 dpaa2_flow_control_log =
3762 getenv("DPAA2_FLOW_CONTROL_LOG");
3764 flow = rte_zmalloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE);
3766 DPAA2_PMD_ERR("Failure to allocate memory for flow");
3769 /* Allocate DMA'ble memory to write the rules */
3770 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3773 "Memory allocation failure for rule configuration\n");
3776 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3779 "Memory allocation failure for rule configuration\n");
3783 flow->qos_rule.key_iova = key_iova;
3784 flow->qos_rule.mask_iova = mask_iova;
3786 /* Allocate DMA'ble memory to write the rules */
3787 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3790 "Memory allocation failure for rule configuration\n");
3793 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3796 "Memory allocation failure for rule configuration\n");
3800 flow->fs_rule.key_iova = key_iova;
3801 flow->fs_rule.mask_iova = mask_iova;
3803 flow->ipaddr_rule.ipaddr_type = FLOW_NONE_IPADDR;
3804 flow->ipaddr_rule.qos_ipsrc_offset =
3805 IP_ADDRESS_OFFSET_INVALID;
3806 flow->ipaddr_rule.qos_ipdst_offset =
3807 IP_ADDRESS_OFFSET_INVALID;
3808 flow->ipaddr_rule.fs_ipsrc_offset =
3809 IP_ADDRESS_OFFSET_INVALID;
3810 flow->ipaddr_rule.fs_ipdst_offset =
3811 IP_ADDRESS_OFFSET_INVALID;
3813 switch (dpaa2_filter_type) {
3814 case RTE_ETH_FILTER_GENERIC:
3815 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern,
3818 if (error->type > RTE_FLOW_ERROR_TYPE_ACTION)
3819 rte_flow_error_set(error, EPERM,
3820 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3823 "Failure to create flow, return code (%d)", ret);
3824 goto creation_error;
3828 DPAA2_PMD_ERR("Filter type (%d) not supported",
3835 rte_flow_error_set(error, EPERM,
3836 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3837 NULL, "memory alloc");
3839 rte_free((void *)flow);
3840 rte_free((void *)key_iova);
3841 rte_free((void *)mask_iova);
3847 int dpaa2_flow_destroy(struct rte_eth_dev *dev,
3848 struct rte_flow *flow,
3849 struct rte_flow_error *error)
3852 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3853 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3855 switch (flow->action) {
3856 case RTE_FLOW_ACTION_TYPE_QUEUE:
3857 if (priv->num_rx_tc > 1) {
3858 /* Remove entry from QoS table first */
3859 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3863 "Error in removing entry from QoS table(%d)", ret);
3868 /* Then remove entry from FS table */
3869 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3870 flow->tc_id, &flow->fs_rule);
3873 "Error in removing entry from FS table(%d)", ret);
3877 case RTE_FLOW_ACTION_TYPE_RSS:
3878 if (priv->num_rx_tc > 1) {
3879 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3883 "Error in entry addition in QoS table(%d)", ret);
3890 "Action type (%d) is not supported", flow->action);
3895 LIST_REMOVE(flow, next);
3896 rte_free((void *)(size_t)flow->qos_rule.key_iova);
3897 rte_free((void *)(size_t)flow->qos_rule.mask_iova);
3898 rte_free((void *)(size_t)flow->fs_rule.key_iova);
3899 rte_free((void *)(size_t)flow->fs_rule.mask_iova);
3900 /* Now free the flow */
3905 rte_flow_error_set(error, EPERM,
3906 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3912 * Destroy user-configured flow rules.
3914 * This function skips internal flows rules.
3916 * @see rte_flow_flush()
3920 dpaa2_flow_flush(struct rte_eth_dev *dev,
3921 struct rte_flow_error *error)
3923 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3924 struct rte_flow *flow = LIST_FIRST(&priv->flows);
3927 struct rte_flow *next = LIST_NEXT(flow, next);
3929 dpaa2_flow_destroy(dev, flow, error);
3936 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
3937 struct rte_flow *flow __rte_unused,
3938 const struct rte_flow_action *actions __rte_unused,
3939 void *data __rte_unused,
3940 struct rte_flow_error *error __rte_unused)
3946 * Clean up all flow rules.
3948 * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
3949 * rules regardless of whether they are internal or user-configured.
3952 * Pointer to private structure.
3955 dpaa2_flow_clean(struct rte_eth_dev *dev)
3957 struct rte_flow *flow;
3958 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3960 while ((flow = LIST_FIRST(&priv->flows)))
3961 dpaa2_flow_destroy(dev, flow, NULL);
3964 const struct rte_flow_ops dpaa2_flow_ops = {
3965 .create = dpaa2_flow_create,
3966 .validate = dpaa2_flow_validate,
3967 .destroy = dpaa2_flow_destroy,
3968 .flush = dpaa2_flow_flush,
3969 .query = dpaa2_flow_query,