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 enum flow_rule_ipaddr_type {
38 struct flow_rule_ipaddr {
39 enum flow_rule_ipaddr_type ipaddr_type;
47 LIST_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
48 struct dpni_rule_cfg qos_rule;
49 struct dpni_rule_cfg fs_rule;
51 uint8_t tc_id; /** Traffic Class ID. */
52 uint8_t tc_index; /** index within this Traffic Class. */
53 enum rte_flow_action_type action;
55 /* Special for IP address to specify the offset
58 struct flow_rule_ipaddr ipaddr_rule;
59 struct dpni_fs_action_cfg action_cfg;
63 enum rte_flow_item_type dpaa2_supported_pattern_type[] = {
64 RTE_FLOW_ITEM_TYPE_END,
65 RTE_FLOW_ITEM_TYPE_ETH,
66 RTE_FLOW_ITEM_TYPE_VLAN,
67 RTE_FLOW_ITEM_TYPE_IPV4,
68 RTE_FLOW_ITEM_TYPE_IPV6,
69 RTE_FLOW_ITEM_TYPE_ICMP,
70 RTE_FLOW_ITEM_TYPE_UDP,
71 RTE_FLOW_ITEM_TYPE_TCP,
72 RTE_FLOW_ITEM_TYPE_SCTP,
73 RTE_FLOW_ITEM_TYPE_GRE,
77 enum rte_flow_action_type dpaa2_supported_action_type[] = {
78 RTE_FLOW_ACTION_TYPE_END,
79 RTE_FLOW_ACTION_TYPE_QUEUE,
80 RTE_FLOW_ACTION_TYPE_RSS
83 /* Max of enum rte_flow_item_type + 1, for both IPv4 and IPv6*/
84 #define DPAA2_FLOW_ITEM_TYPE_GENERIC_IP (RTE_FLOW_ITEM_TYPE_META + 1)
86 enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE;
89 static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = {
90 .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
91 .src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
92 .type = RTE_BE16(0xffff),
95 static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = {
96 .tci = RTE_BE16(0xffff),
99 static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = {
100 .hdr.src_addr = RTE_BE32(0xffffffff),
101 .hdr.dst_addr = RTE_BE32(0xffffffff),
102 .hdr.next_proto_id = 0xff,
105 static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = {
108 "\xff\xff\xff\xff\xff\xff\xff\xff"
109 "\xff\xff\xff\xff\xff\xff\xff\xff",
111 "\xff\xff\xff\xff\xff\xff\xff\xff"
112 "\xff\xff\xff\xff\xff\xff\xff\xff",
117 static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = {
118 .hdr.icmp_type = 0xff,
119 .hdr.icmp_code = 0xff,
122 static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = {
124 .src_port = RTE_BE16(0xffff),
125 .dst_port = RTE_BE16(0xffff),
129 static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = {
131 .src_port = RTE_BE16(0xffff),
132 .dst_port = RTE_BE16(0xffff),
136 static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = {
138 .src_port = RTE_BE16(0xffff),
139 .dst_port = RTE_BE16(0xffff),
143 static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = {
144 .protocol = RTE_BE16(0xffff),
150 static inline void dpaa2_flow_extract_key_set(
151 struct dpaa2_key_info *key_info, int index, uint8_t size)
153 key_info->key_size[index] = size;
155 key_info->key_offset[index] =
156 key_info->key_offset[index - 1] +
157 key_info->key_size[index - 1];
159 key_info->key_offset[index] = 0;
161 key_info->key_total_size += size;
164 static int dpaa2_flow_extract_add(
165 struct dpaa2_key_extract *key_extract,
167 uint32_t field, uint8_t field_size)
169 int index, ip_src = -1, ip_dst = -1;
170 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
171 struct dpaa2_key_info *key_info = &key_extract->key_info;
173 if (dpkg->num_extracts >=
174 DPKG_MAX_NUM_OF_EXTRACTS) {
175 DPAA2_PMD_WARN("Number of extracts overflows");
178 /* Before reorder, the IP SRC and IP DST are already last
181 for (index = 0; index < dpkg->num_extracts; index++) {
182 if (dpkg->extracts[index].extract.from_hdr.prot ==
184 if (dpkg->extracts[index].extract.from_hdr.field ==
188 if (dpkg->extracts[index].extract.from_hdr.field ==
196 RTE_ASSERT((ip_src + 2) >= dpkg->num_extracts);
199 RTE_ASSERT((ip_dst + 2) >= dpkg->num_extracts);
201 if (prot == NET_PROT_IP &&
202 (field == NH_FLD_IP_SRC ||
203 field == NH_FLD_IP_DST)) {
204 index = dpkg->num_extracts;
206 if (ip_src >= 0 && ip_dst >= 0)
207 index = dpkg->num_extracts - 2;
208 else if (ip_src >= 0 || ip_dst >= 0)
209 index = dpkg->num_extracts - 1;
211 index = dpkg->num_extracts;
214 dpkg->extracts[index].type = DPKG_EXTRACT_FROM_HDR;
215 dpkg->extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD;
216 dpkg->extracts[index].extract.from_hdr.prot = prot;
217 dpkg->extracts[index].extract.from_hdr.field = field;
218 if (prot == NET_PROT_IP &&
219 (field == NH_FLD_IP_SRC ||
220 field == NH_FLD_IP_DST)) {
221 dpaa2_flow_extract_key_set(key_info, index, 0);
223 dpaa2_flow_extract_key_set(key_info, index, field_size);
226 if (prot == NET_PROT_IP) {
227 if (field == NH_FLD_IP_SRC) {
228 if (key_info->ipv4_dst_offset >= 0) {
229 key_info->ipv4_src_offset =
230 key_info->ipv4_dst_offset +
231 NH_FLD_IPV4_ADDR_SIZE;
233 key_info->ipv4_src_offset =
234 key_info->key_offset[index - 1] +
235 key_info->key_size[index - 1];
237 if (key_info->ipv6_dst_offset >= 0) {
238 key_info->ipv6_src_offset =
239 key_info->ipv6_dst_offset +
240 NH_FLD_IPV6_ADDR_SIZE;
242 key_info->ipv6_src_offset =
243 key_info->key_offset[index - 1] +
244 key_info->key_size[index - 1];
246 } else if (field == NH_FLD_IP_DST) {
247 if (key_info->ipv4_src_offset >= 0) {
248 key_info->ipv4_dst_offset =
249 key_info->ipv4_src_offset +
250 NH_FLD_IPV4_ADDR_SIZE;
252 key_info->ipv4_dst_offset =
253 key_info->key_offset[index - 1] +
254 key_info->key_size[index - 1];
256 if (key_info->ipv6_src_offset >= 0) {
257 key_info->ipv6_dst_offset =
258 key_info->ipv6_src_offset +
259 NH_FLD_IPV6_ADDR_SIZE;
261 key_info->ipv6_dst_offset =
262 key_info->key_offset[index - 1] +
263 key_info->key_size[index - 1];
268 if (index == dpkg->num_extracts) {
269 dpkg->num_extracts++;
275 dpkg->extracts[ip_src].type =
276 DPKG_EXTRACT_FROM_HDR;
277 dpkg->extracts[ip_src].extract.from_hdr.type =
279 dpkg->extracts[ip_src].extract.from_hdr.prot =
281 dpkg->extracts[ip_src].extract.from_hdr.field =
283 dpaa2_flow_extract_key_set(key_info, ip_src, 0);
284 key_info->ipv4_src_offset += field_size;
285 key_info->ipv6_src_offset += field_size;
289 dpkg->extracts[ip_dst].type =
290 DPKG_EXTRACT_FROM_HDR;
291 dpkg->extracts[ip_dst].extract.from_hdr.type =
293 dpkg->extracts[ip_dst].extract.from_hdr.prot =
295 dpkg->extracts[ip_dst].extract.from_hdr.field =
297 dpaa2_flow_extract_key_set(key_info, ip_dst, 0);
298 key_info->ipv4_dst_offset += field_size;
299 key_info->ipv6_dst_offset += field_size;
302 dpkg->num_extracts++;
307 /* Protocol discrimination.
308 * Discriminate IPv4/IPv6/vLan by Eth type.
309 * Discriminate UDP/TCP/ICMP by next proto of IP.
312 dpaa2_flow_proto_discrimination_extract(
313 struct dpaa2_key_extract *key_extract,
314 enum rte_flow_item_type type)
316 if (type == RTE_FLOW_ITEM_TYPE_ETH) {
317 return dpaa2_flow_extract_add(
318 key_extract, NET_PROT_ETH,
321 } else if (type == (enum rte_flow_item_type)
322 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
323 return dpaa2_flow_extract_add(
324 key_extract, NET_PROT_IP,
326 NH_FLD_IP_PROTO_SIZE);
332 static inline int dpaa2_flow_extract_search(
333 struct dpkg_profile_cfg *dpkg,
334 enum net_prot prot, uint32_t field)
338 for (i = 0; i < dpkg->num_extracts; i++) {
339 if (dpkg->extracts[i].extract.from_hdr.prot == prot &&
340 dpkg->extracts[i].extract.from_hdr.field == field) {
348 static inline int dpaa2_flow_extract_key_offset(
349 struct dpaa2_key_extract *key_extract,
350 enum net_prot prot, uint32_t field)
353 struct dpkg_profile_cfg *dpkg = &key_extract->dpkg;
354 struct dpaa2_key_info *key_info = &key_extract->key_info;
356 if (prot == NET_PROT_IPV4 ||
357 prot == NET_PROT_IPV6)
358 i = dpaa2_flow_extract_search(dpkg, NET_PROT_IP, field);
360 i = dpaa2_flow_extract_search(dpkg, prot, field);
363 if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_SRC)
364 return key_info->ipv4_src_offset;
365 else if (prot == NET_PROT_IPV4 && field == NH_FLD_IP_DST)
366 return key_info->ipv4_dst_offset;
367 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_SRC)
368 return key_info->ipv6_src_offset;
369 else if (prot == NET_PROT_IPV6 && field == NH_FLD_IP_DST)
370 return key_info->ipv6_dst_offset;
372 return key_info->key_offset[i];
378 struct proto_discrimination {
379 enum rte_flow_item_type type;
387 dpaa2_flow_proto_discrimination_rule(
388 struct dpaa2_dev_priv *priv, struct rte_flow *flow,
389 struct proto_discrimination proto, int group)
399 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
401 field = NH_FLD_ETH_TYPE;
402 } else if (proto.type == DPAA2_FLOW_ITEM_TYPE_GENERIC_IP) {
404 field = NH_FLD_IP_PROTO;
407 "Only Eth and IP support to discriminate next proto.");
411 offset = dpaa2_flow_extract_key_offset(&priv->extract.qos_key_extract,
414 DPAA2_PMD_ERR("QoS prot %d field %d extract failed",
418 key_iova = flow->qos_rule.key_iova + offset;
419 mask_iova = flow->qos_rule.mask_iova + offset;
420 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
421 eth_type = proto.eth_type;
422 memcpy((void *)key_iova, (const void *)(ð_type),
425 memcpy((void *)mask_iova, (const void *)(ð_type),
428 ip_proto = proto.ip_proto;
429 memcpy((void *)key_iova, (const void *)(&ip_proto),
432 memcpy((void *)mask_iova, (const void *)(&ip_proto),
436 offset = dpaa2_flow_extract_key_offset(
437 &priv->extract.tc_key_extract[group],
440 DPAA2_PMD_ERR("FS prot %d field %d extract failed",
444 key_iova = flow->fs_rule.key_iova + offset;
445 mask_iova = flow->fs_rule.mask_iova + offset;
447 if (proto.type == RTE_FLOW_ITEM_TYPE_ETH) {
448 eth_type = proto.eth_type;
449 memcpy((void *)key_iova, (const void *)(ð_type),
452 memcpy((void *)mask_iova, (const void *)(ð_type),
455 ip_proto = proto.ip_proto;
456 memcpy((void *)key_iova, (const void *)(&ip_proto),
459 memcpy((void *)mask_iova, (const void *)(&ip_proto),
467 dpaa2_flow_rule_data_set(
468 struct dpaa2_key_extract *key_extract,
469 struct dpni_rule_cfg *rule,
470 enum net_prot prot, uint32_t field,
471 const void *key, const void *mask, int size)
473 int offset = dpaa2_flow_extract_key_offset(key_extract,
477 DPAA2_PMD_ERR("prot %d, field %d extract failed",
481 memcpy((void *)(size_t)(rule->key_iova + offset), key, size);
482 memcpy((void *)(size_t)(rule->mask_iova + offset), mask, size);
488 _dpaa2_flow_rule_move_ipaddr_tail(
489 struct dpaa2_key_extract *key_extract,
490 struct dpni_rule_cfg *rule, int src_offset,
491 uint32_t field, bool ipv4)
499 char tmp[NH_FLD_IPV6_ADDR_SIZE];
501 if (field != NH_FLD_IP_SRC &&
502 field != NH_FLD_IP_DST) {
503 DPAA2_PMD_ERR("Field of IP addr reorder must be IP SRC/DST");
507 prot = NET_PROT_IPV4;
509 prot = NET_PROT_IPV6;
510 dst_offset = dpaa2_flow_extract_key_offset(key_extract,
512 if (dst_offset < 0) {
513 DPAA2_PMD_ERR("Field %d reorder extract failed", field);
516 key_src = rule->key_iova + src_offset;
517 mask_src = rule->mask_iova + src_offset;
518 key_dst = rule->key_iova + dst_offset;
519 mask_dst = rule->mask_iova + dst_offset;
521 len = sizeof(rte_be32_t);
523 len = NH_FLD_IPV6_ADDR_SIZE;
525 memcpy(tmp, (char *)key_src, len);
526 memcpy((char *)key_dst, tmp, len);
528 memcpy(tmp, (char *)mask_src, len);
529 memcpy((char *)mask_dst, tmp, len);
535 dpaa2_flow_rule_move_ipaddr_tail(
536 struct rte_flow *flow, struct dpaa2_dev_priv *priv,
542 if (flow->ipaddr_rule.ipaddr_type == FLOW_NONE_IPADDR)
545 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR)
546 prot = NET_PROT_IPV4;
548 prot = NET_PROT_IPV6;
550 if (flow->ipaddr_rule.qos_ipsrc_offset >= 0) {
551 ret = _dpaa2_flow_rule_move_ipaddr_tail(
552 &priv->extract.qos_key_extract,
554 flow->ipaddr_rule.qos_ipsrc_offset,
555 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
557 DPAA2_PMD_ERR("QoS src address reorder failed");
560 flow->ipaddr_rule.qos_ipsrc_offset =
561 dpaa2_flow_extract_key_offset(
562 &priv->extract.qos_key_extract,
563 prot, NH_FLD_IP_SRC);
566 if (flow->ipaddr_rule.qos_ipdst_offset >= 0) {
567 ret = _dpaa2_flow_rule_move_ipaddr_tail(
568 &priv->extract.qos_key_extract,
570 flow->ipaddr_rule.qos_ipdst_offset,
571 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
573 DPAA2_PMD_ERR("QoS dst address reorder failed");
576 flow->ipaddr_rule.qos_ipdst_offset =
577 dpaa2_flow_extract_key_offset(
578 &priv->extract.qos_key_extract,
579 prot, NH_FLD_IP_DST);
582 if (flow->ipaddr_rule.fs_ipsrc_offset >= 0) {
583 ret = _dpaa2_flow_rule_move_ipaddr_tail(
584 &priv->extract.tc_key_extract[fs_group],
586 flow->ipaddr_rule.fs_ipsrc_offset,
587 NH_FLD_IP_SRC, prot == NET_PROT_IPV4);
589 DPAA2_PMD_ERR("FS src address reorder failed");
592 flow->ipaddr_rule.fs_ipsrc_offset =
593 dpaa2_flow_extract_key_offset(
594 &priv->extract.tc_key_extract[fs_group],
595 prot, NH_FLD_IP_SRC);
597 if (flow->ipaddr_rule.fs_ipdst_offset >= 0) {
598 ret = _dpaa2_flow_rule_move_ipaddr_tail(
599 &priv->extract.tc_key_extract[fs_group],
601 flow->ipaddr_rule.fs_ipdst_offset,
602 NH_FLD_IP_DST, prot == NET_PROT_IPV4);
604 DPAA2_PMD_ERR("FS dst address reorder failed");
607 flow->ipaddr_rule.fs_ipdst_offset =
608 dpaa2_flow_extract_key_offset(
609 &priv->extract.tc_key_extract[fs_group],
610 prot, NH_FLD_IP_DST);
617 dpaa2_flow_extract_support(
618 const uint8_t *mask_src,
619 enum rte_flow_item_type type)
623 const char *mask_support = 0;
626 case RTE_FLOW_ITEM_TYPE_ETH:
627 mask_support = (const char *)&dpaa2_flow_item_eth_mask;
628 size = sizeof(struct rte_flow_item_eth);
630 case RTE_FLOW_ITEM_TYPE_VLAN:
631 mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
632 size = sizeof(struct rte_flow_item_vlan);
634 case RTE_FLOW_ITEM_TYPE_IPV4:
635 mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
636 size = sizeof(struct rte_flow_item_ipv4);
638 case RTE_FLOW_ITEM_TYPE_IPV6:
639 mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
640 size = sizeof(struct rte_flow_item_ipv6);
642 case RTE_FLOW_ITEM_TYPE_ICMP:
643 mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
644 size = sizeof(struct rte_flow_item_icmp);
646 case RTE_FLOW_ITEM_TYPE_UDP:
647 mask_support = (const char *)&dpaa2_flow_item_udp_mask;
648 size = sizeof(struct rte_flow_item_udp);
650 case RTE_FLOW_ITEM_TYPE_TCP:
651 mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
652 size = sizeof(struct rte_flow_item_tcp);
654 case RTE_FLOW_ITEM_TYPE_SCTP:
655 mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
656 size = sizeof(struct rte_flow_item_sctp);
658 case RTE_FLOW_ITEM_TYPE_GRE:
659 mask_support = (const char *)&dpaa2_flow_item_gre_mask;
660 size = sizeof(struct rte_flow_item_gre);
666 memcpy(mask, mask_support, size);
668 for (i = 0; i < size; i++)
669 mask[i] = (mask[i] | mask_src[i]);
671 if (memcmp(mask, mask_support, size))
678 dpaa2_configure_flow_eth(struct rte_flow *flow,
679 struct rte_eth_dev *dev,
680 const struct rte_flow_attr *attr,
681 const struct rte_flow_item *pattern,
682 const struct rte_flow_action actions[] __rte_unused,
683 struct rte_flow_error *error __rte_unused,
684 int *device_configured)
689 const struct rte_flow_item_eth *spec, *mask;
691 /* TODO: Currently upper bound of range parameter is not implemented */
692 const struct rte_flow_item_eth *last __rte_unused;
693 struct dpaa2_dev_priv *priv = dev->data->dev_private;
694 const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
698 /* Parse pattern list to get the matching parameters */
699 spec = (const struct rte_flow_item_eth *)pattern->spec;
700 last = (const struct rte_flow_item_eth *)pattern->last;
701 mask = (const struct rte_flow_item_eth *)
702 (pattern->mask ? pattern->mask : &dpaa2_flow_item_eth_mask);
704 /* Don't care any field of eth header,
705 * only care eth protocol.
707 DPAA2_PMD_WARN("No pattern spec for Eth flow, just skip");
711 /* Get traffic class index and flow id to be configured */
713 flow->tc_index = attr->priority;
715 if (dpaa2_flow_extract_support((const uint8_t *)mask,
716 RTE_FLOW_ITEM_TYPE_ETH)) {
717 DPAA2_PMD_WARN("Extract field(s) of ethernet not support.");
722 if (memcmp((const char *)&mask->src, zero_cmp, RTE_ETHER_ADDR_LEN)) {
723 index = dpaa2_flow_extract_search(
724 &priv->extract.qos_key_extract.dpkg,
725 NET_PROT_ETH, NH_FLD_ETH_SA);
727 ret = dpaa2_flow_extract_add(
728 &priv->extract.qos_key_extract,
729 NET_PROT_ETH, NH_FLD_ETH_SA,
732 DPAA2_PMD_ERR("QoS Extract add ETH_SA failed.");
736 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
738 index = dpaa2_flow_extract_search(
739 &priv->extract.tc_key_extract[group].dpkg,
740 NET_PROT_ETH, NH_FLD_ETH_SA);
742 ret = dpaa2_flow_extract_add(
743 &priv->extract.tc_key_extract[group],
744 NET_PROT_ETH, NH_FLD_ETH_SA,
747 DPAA2_PMD_ERR("FS Extract add ETH_SA failed.");
750 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
753 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
756 "Move ipaddr before ETH_SA rule set failed");
760 ret = dpaa2_flow_rule_data_set(
761 &priv->extract.qos_key_extract,
765 &spec->src.addr_bytes,
766 &mask->src.addr_bytes,
767 sizeof(struct rte_ether_addr));
769 DPAA2_PMD_ERR("QoS NH_FLD_ETH_SA rule data set failed");
773 ret = dpaa2_flow_rule_data_set(
774 &priv->extract.tc_key_extract[group],
778 &spec->src.addr_bytes,
779 &mask->src.addr_bytes,
780 sizeof(struct rte_ether_addr));
782 DPAA2_PMD_ERR("FS NH_FLD_ETH_SA rule data set failed");
787 if (memcmp((const char *)&mask->dst, zero_cmp, RTE_ETHER_ADDR_LEN)) {
788 index = dpaa2_flow_extract_search(
789 &priv->extract.qos_key_extract.dpkg,
790 NET_PROT_ETH, NH_FLD_ETH_DA);
792 ret = dpaa2_flow_extract_add(
793 &priv->extract.qos_key_extract,
794 NET_PROT_ETH, NH_FLD_ETH_DA,
797 DPAA2_PMD_ERR("QoS Extract add ETH_DA failed.");
801 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
804 index = dpaa2_flow_extract_search(
805 &priv->extract.tc_key_extract[group].dpkg,
806 NET_PROT_ETH, NH_FLD_ETH_DA);
808 ret = dpaa2_flow_extract_add(
809 &priv->extract.tc_key_extract[group],
810 NET_PROT_ETH, NH_FLD_ETH_DA,
813 DPAA2_PMD_ERR("FS Extract add ETH_DA failed.");
817 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
820 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
823 "Move ipaddr before ETH DA rule set failed");
827 ret = dpaa2_flow_rule_data_set(
828 &priv->extract.qos_key_extract,
832 &spec->dst.addr_bytes,
833 &mask->dst.addr_bytes,
834 sizeof(struct rte_ether_addr));
836 DPAA2_PMD_ERR("QoS NH_FLD_ETH_DA rule data set failed");
840 ret = dpaa2_flow_rule_data_set(
841 &priv->extract.tc_key_extract[group],
845 &spec->dst.addr_bytes,
846 &mask->dst.addr_bytes,
847 sizeof(struct rte_ether_addr));
849 DPAA2_PMD_ERR("FS NH_FLD_ETH_DA rule data set failed");
854 if (memcmp((const char *)&mask->type, zero_cmp, sizeof(rte_be16_t))) {
855 index = dpaa2_flow_extract_search(
856 &priv->extract.qos_key_extract.dpkg,
857 NET_PROT_ETH, NH_FLD_ETH_TYPE);
859 ret = dpaa2_flow_extract_add(
860 &priv->extract.qos_key_extract,
861 NET_PROT_ETH, NH_FLD_ETH_TYPE,
864 DPAA2_PMD_ERR("QoS Extract add ETH_TYPE failed.");
868 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
870 index = dpaa2_flow_extract_search(
871 &priv->extract.tc_key_extract[group].dpkg,
872 NET_PROT_ETH, NH_FLD_ETH_TYPE);
874 ret = dpaa2_flow_extract_add(
875 &priv->extract.tc_key_extract[group],
876 NET_PROT_ETH, NH_FLD_ETH_TYPE,
879 DPAA2_PMD_ERR("FS Extract add ETH_TYPE failed.");
883 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
886 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
889 "Move ipaddr before ETH TYPE rule set failed");
893 ret = dpaa2_flow_rule_data_set(
894 &priv->extract.qos_key_extract,
902 DPAA2_PMD_ERR("QoS NH_FLD_ETH_TYPE rule data set failed");
906 ret = dpaa2_flow_rule_data_set(
907 &priv->extract.tc_key_extract[group],
915 DPAA2_PMD_ERR("FS NH_FLD_ETH_TYPE rule data set failed");
920 (*device_configured) |= local_cfg;
926 dpaa2_configure_flow_vlan(struct rte_flow *flow,
927 struct rte_eth_dev *dev,
928 const struct rte_flow_attr *attr,
929 const struct rte_flow_item *pattern,
930 const struct rte_flow_action actions[] __rte_unused,
931 struct rte_flow_error *error __rte_unused,
932 int *device_configured)
937 const struct rte_flow_item_vlan *spec, *mask;
939 const struct rte_flow_item_vlan *last __rte_unused;
940 struct dpaa2_dev_priv *priv = dev->data->dev_private;
944 /* Parse pattern list to get the matching parameters */
945 spec = (const struct rte_flow_item_vlan *)pattern->spec;
946 last = (const struct rte_flow_item_vlan *)pattern->last;
947 mask = (const struct rte_flow_item_vlan *)
948 (pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask);
950 /* Get traffic class index and flow id to be configured */
952 flow->tc_index = attr->priority;
955 /* Don't care any field of vlan header,
956 * only care vlan protocol.
958 /* Eth type is actually used for vLan classification.
960 struct proto_discrimination proto;
962 index = dpaa2_flow_extract_search(
963 &priv->extract.qos_key_extract.dpkg,
964 NET_PROT_ETH, NH_FLD_ETH_TYPE);
966 ret = dpaa2_flow_proto_discrimination_extract(
967 &priv->extract.qos_key_extract,
968 RTE_FLOW_ITEM_TYPE_ETH);
971 "QoS Ext ETH_TYPE to discriminate vLan failed");
975 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
978 index = dpaa2_flow_extract_search(
979 &priv->extract.tc_key_extract[group].dpkg,
980 NET_PROT_ETH, NH_FLD_ETH_TYPE);
982 ret = dpaa2_flow_proto_discrimination_extract(
983 &priv->extract.tc_key_extract[group],
984 RTE_FLOW_ITEM_TYPE_ETH);
987 "FS Ext ETH_TYPE to discriminate vLan failed.");
991 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
994 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
997 "Move ipaddr before vLan discrimination set failed");
1001 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1002 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
1003 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1006 DPAA2_PMD_ERR("vLan discrimination rule set failed");
1010 (*device_configured) |= local_cfg;
1015 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1016 RTE_FLOW_ITEM_TYPE_VLAN)) {
1017 DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
1025 index = dpaa2_flow_extract_search(
1026 &priv->extract.qos_key_extract.dpkg,
1027 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1029 ret = dpaa2_flow_extract_add(
1030 &priv->extract.qos_key_extract,
1033 sizeof(rte_be16_t));
1035 DPAA2_PMD_ERR("QoS Extract add VLAN_TCI failed.");
1039 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1042 index = dpaa2_flow_extract_search(
1043 &priv->extract.tc_key_extract[group].dpkg,
1044 NET_PROT_VLAN, NH_FLD_VLAN_TCI);
1046 ret = dpaa2_flow_extract_add(
1047 &priv->extract.tc_key_extract[group],
1050 sizeof(rte_be16_t));
1052 DPAA2_PMD_ERR("FS Extract add VLAN_TCI failed.");
1056 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1059 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1062 "Move ipaddr before VLAN TCI rule set failed");
1066 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
1072 sizeof(rte_be16_t));
1074 DPAA2_PMD_ERR("QoS NH_FLD_VLAN_TCI rule data set failed");
1078 ret = dpaa2_flow_rule_data_set(
1079 &priv->extract.tc_key_extract[group],
1085 sizeof(rte_be16_t));
1087 DPAA2_PMD_ERR("FS NH_FLD_VLAN_TCI rule data set failed");
1091 (*device_configured) |= local_cfg;
1097 dpaa2_configure_flow_generic_ip(
1098 struct rte_flow *flow,
1099 struct rte_eth_dev *dev,
1100 const struct rte_flow_attr *attr,
1101 const struct rte_flow_item *pattern,
1102 const struct rte_flow_action actions[] __rte_unused,
1103 struct rte_flow_error *error __rte_unused,
1104 int *device_configured)
1109 const struct rte_flow_item_ipv4 *spec_ipv4 = 0,
1111 const struct rte_flow_item_ipv6 *spec_ipv6 = 0,
1113 const void *key, *mask;
1116 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1117 const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
1120 group = attr->group;
1122 /* Parse pattern list to get the matching parameters */
1123 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1124 spec_ipv4 = (const struct rte_flow_item_ipv4 *)pattern->spec;
1125 mask_ipv4 = (const struct rte_flow_item_ipv4 *)
1126 (pattern->mask ? pattern->mask :
1127 &dpaa2_flow_item_ipv4_mask);
1129 spec_ipv6 = (const struct rte_flow_item_ipv6 *)pattern->spec;
1130 mask_ipv6 = (const struct rte_flow_item_ipv6 *)
1131 (pattern->mask ? pattern->mask :
1132 &dpaa2_flow_item_ipv6_mask);
1135 /* Get traffic class index and flow id to be configured */
1136 flow->tc_id = group;
1137 flow->tc_index = attr->priority;
1139 if (!spec_ipv4 && !spec_ipv6) {
1140 /* Don't care any field of IP header,
1141 * only care IP protocol.
1142 * Example: flow create 0 ingress pattern ipv6 /
1144 /* Eth type is actually used for IP identification.
1146 /* TODO: Current design only supports Eth + IP,
1147 * Eth + vLan + IP needs to add.
1149 struct proto_discrimination proto;
1151 index = dpaa2_flow_extract_search(
1152 &priv->extract.qos_key_extract.dpkg,
1153 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1155 ret = dpaa2_flow_proto_discrimination_extract(
1156 &priv->extract.qos_key_extract,
1157 RTE_FLOW_ITEM_TYPE_ETH);
1160 "QoS Ext ETH_TYPE to discriminate IP failed.");
1164 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1167 index = dpaa2_flow_extract_search(
1168 &priv->extract.tc_key_extract[group].dpkg,
1169 NET_PROT_ETH, NH_FLD_ETH_TYPE);
1171 ret = dpaa2_flow_proto_discrimination_extract(
1172 &priv->extract.tc_key_extract[group],
1173 RTE_FLOW_ITEM_TYPE_ETH);
1176 "FS Ext ETH_TYPE to discriminate IP failed");
1180 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1183 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1186 "Move ipaddr before IP discrimination set failed");
1190 proto.type = RTE_FLOW_ITEM_TYPE_ETH;
1191 if (pattern->type == RTE_FLOW_ITEM_TYPE_IPV4)
1192 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
1194 proto.eth_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
1195 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1198 DPAA2_PMD_ERR("IP discrimination rule set failed");
1202 (*device_configured) |= local_cfg;
1208 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
1209 RTE_FLOW_ITEM_TYPE_IPV4)) {
1210 DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
1217 if (dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
1218 RTE_FLOW_ITEM_TYPE_IPV6)) {
1219 DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
1225 if (mask_ipv4 && (mask_ipv4->hdr.src_addr ||
1226 mask_ipv4->hdr.dst_addr)) {
1227 flow->ipaddr_rule.ipaddr_type = FLOW_IPV4_ADDR;
1228 } else if (mask_ipv6 &&
1229 (memcmp((const char *)mask_ipv6->hdr.src_addr,
1230 zero_cmp, NH_FLD_IPV6_ADDR_SIZE) ||
1231 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1232 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1233 flow->ipaddr_rule.ipaddr_type = FLOW_IPV6_ADDR;
1236 if ((mask_ipv4 && mask_ipv4->hdr.src_addr) ||
1238 memcmp((const char *)mask_ipv6->hdr.src_addr,
1239 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1240 index = dpaa2_flow_extract_search(
1241 &priv->extract.qos_key_extract.dpkg,
1242 NET_PROT_IP, NH_FLD_IP_SRC);
1244 ret = dpaa2_flow_extract_add(
1245 &priv->extract.qos_key_extract,
1250 DPAA2_PMD_ERR("QoS Extract add IP_SRC failed.");
1254 local_cfg |= (DPAA2_QOS_TABLE_RECONFIGURE |
1255 DPAA2_QOS_TABLE_IPADDR_EXTRACT);
1258 index = dpaa2_flow_extract_search(
1259 &priv->extract.tc_key_extract[group].dpkg,
1260 NET_PROT_IP, NH_FLD_IP_SRC);
1262 ret = dpaa2_flow_extract_add(
1263 &priv->extract.tc_key_extract[group],
1268 DPAA2_PMD_ERR("FS Extract add IP_SRC failed.");
1272 local_cfg |= (DPAA2_FS_TABLE_RECONFIGURE |
1273 DPAA2_FS_TABLE_IPADDR_EXTRACT);
1277 key = &spec_ipv4->hdr.src_addr;
1279 key = &spec_ipv6->hdr.src_addr[0];
1281 mask = &mask_ipv4->hdr.src_addr;
1282 size = NH_FLD_IPV4_ADDR_SIZE;
1283 prot = NET_PROT_IPV4;
1285 mask = &mask_ipv6->hdr.src_addr[0];
1286 size = NH_FLD_IPV6_ADDR_SIZE;
1287 prot = NET_PROT_IPV6;
1290 ret = dpaa2_flow_rule_data_set(
1291 &priv->extract.qos_key_extract,
1293 prot, NH_FLD_IP_SRC,
1296 DPAA2_PMD_ERR("QoS NH_FLD_IP_SRC rule data set failed");
1300 ret = dpaa2_flow_rule_data_set(
1301 &priv->extract.tc_key_extract[group],
1303 prot, NH_FLD_IP_SRC,
1306 DPAA2_PMD_ERR("FS NH_FLD_IP_SRC rule data set failed");
1310 flow->ipaddr_rule.qos_ipsrc_offset =
1311 dpaa2_flow_extract_key_offset(
1312 &priv->extract.qos_key_extract,
1313 prot, NH_FLD_IP_SRC);
1314 flow->ipaddr_rule.fs_ipsrc_offset =
1315 dpaa2_flow_extract_key_offset(
1316 &priv->extract.tc_key_extract[group],
1317 prot, NH_FLD_IP_SRC);
1320 if ((mask_ipv4 && mask_ipv4->hdr.dst_addr) ||
1322 memcmp((const char *)mask_ipv6->hdr.dst_addr,
1323 zero_cmp, NH_FLD_IPV6_ADDR_SIZE))) {
1324 index = dpaa2_flow_extract_search(
1325 &priv->extract.qos_key_extract.dpkg,
1326 NET_PROT_IP, NH_FLD_IP_DST);
1329 size = NH_FLD_IPV4_ADDR_SIZE;
1331 size = NH_FLD_IPV6_ADDR_SIZE;
1332 ret = dpaa2_flow_extract_add(
1333 &priv->extract.qos_key_extract,
1338 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1342 local_cfg |= (DPAA2_QOS_TABLE_RECONFIGURE |
1343 DPAA2_QOS_TABLE_IPADDR_EXTRACT);
1346 index = dpaa2_flow_extract_search(
1347 &priv->extract.tc_key_extract[group].dpkg,
1348 NET_PROT_IP, NH_FLD_IP_DST);
1351 size = NH_FLD_IPV4_ADDR_SIZE;
1353 size = NH_FLD_IPV6_ADDR_SIZE;
1354 ret = dpaa2_flow_extract_add(
1355 &priv->extract.tc_key_extract[group],
1360 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1364 local_cfg |= (DPAA2_FS_TABLE_RECONFIGURE |
1365 DPAA2_FS_TABLE_IPADDR_EXTRACT);
1369 key = &spec_ipv4->hdr.dst_addr;
1371 key = spec_ipv6->hdr.dst_addr;
1373 mask = &mask_ipv4->hdr.dst_addr;
1374 size = NH_FLD_IPV4_ADDR_SIZE;
1375 prot = NET_PROT_IPV4;
1377 mask = &mask_ipv6->hdr.dst_addr[0];
1378 size = NH_FLD_IPV6_ADDR_SIZE;
1379 prot = NET_PROT_IPV6;
1382 ret = dpaa2_flow_rule_data_set(
1383 &priv->extract.qos_key_extract,
1385 prot, NH_FLD_IP_DST,
1388 DPAA2_PMD_ERR("QoS NH_FLD_IP_DST rule data set failed");
1392 ret = dpaa2_flow_rule_data_set(
1393 &priv->extract.tc_key_extract[group],
1395 prot, NH_FLD_IP_DST,
1398 DPAA2_PMD_ERR("FS NH_FLD_IP_DST rule data set failed");
1401 flow->ipaddr_rule.qos_ipdst_offset =
1402 dpaa2_flow_extract_key_offset(
1403 &priv->extract.qos_key_extract,
1404 prot, NH_FLD_IP_DST);
1405 flow->ipaddr_rule.fs_ipdst_offset =
1406 dpaa2_flow_extract_key_offset(
1407 &priv->extract.tc_key_extract[group],
1408 prot, NH_FLD_IP_DST);
1411 if ((mask_ipv4 && mask_ipv4->hdr.next_proto_id) ||
1412 (mask_ipv6 && mask_ipv6->hdr.proto)) {
1413 index = dpaa2_flow_extract_search(
1414 &priv->extract.qos_key_extract.dpkg,
1415 NET_PROT_IP, NH_FLD_IP_PROTO);
1417 ret = dpaa2_flow_extract_add(
1418 &priv->extract.qos_key_extract,
1421 NH_FLD_IP_PROTO_SIZE);
1423 DPAA2_PMD_ERR("QoS Extract add IP_DST failed.");
1427 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1430 index = dpaa2_flow_extract_search(
1431 &priv->extract.tc_key_extract[group].dpkg,
1432 NET_PROT_IP, NH_FLD_IP_PROTO);
1434 ret = dpaa2_flow_extract_add(
1435 &priv->extract.tc_key_extract[group],
1438 NH_FLD_IP_PROTO_SIZE);
1440 DPAA2_PMD_ERR("FS Extract add IP_DST failed.");
1444 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1447 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1450 "Move ipaddr after NH_FLD_IP_PROTO rule set failed");
1455 key = &spec_ipv4->hdr.next_proto_id;
1457 key = &spec_ipv6->hdr.proto;
1459 mask = &mask_ipv4->hdr.next_proto_id;
1461 mask = &mask_ipv6->hdr.proto;
1463 ret = dpaa2_flow_rule_data_set(
1464 &priv->extract.qos_key_extract,
1468 key, mask, NH_FLD_IP_PROTO_SIZE);
1470 DPAA2_PMD_ERR("QoS NH_FLD_IP_PROTO rule data set failed");
1474 ret = dpaa2_flow_rule_data_set(
1475 &priv->extract.tc_key_extract[group],
1479 key, mask, NH_FLD_IP_PROTO_SIZE);
1481 DPAA2_PMD_ERR("FS NH_FLD_IP_PROTO rule data set failed");
1486 (*device_configured) |= local_cfg;
1492 dpaa2_configure_flow_icmp(struct rte_flow *flow,
1493 struct rte_eth_dev *dev,
1494 const struct rte_flow_attr *attr,
1495 const struct rte_flow_item *pattern,
1496 const struct rte_flow_action actions[] __rte_unused,
1497 struct rte_flow_error *error __rte_unused,
1498 int *device_configured)
1503 const struct rte_flow_item_icmp *spec, *mask;
1505 const struct rte_flow_item_icmp *last __rte_unused;
1506 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1508 group = attr->group;
1510 /* Parse pattern list to get the matching parameters */
1511 spec = (const struct rte_flow_item_icmp *)pattern->spec;
1512 last = (const struct rte_flow_item_icmp *)pattern->last;
1513 mask = (const struct rte_flow_item_icmp *)
1514 (pattern->mask ? pattern->mask : &dpaa2_flow_item_icmp_mask);
1516 /* Get traffic class index and flow id to be configured */
1517 flow->tc_id = group;
1518 flow->tc_index = attr->priority;
1521 /* Don't care any field of ICMP header,
1522 * only care ICMP protocol.
1523 * Example: flow create 0 ingress pattern icmp /
1525 /* Next proto of Generical IP is actually used
1526 * for ICMP identification.
1528 struct proto_discrimination proto;
1530 index = dpaa2_flow_extract_search(
1531 &priv->extract.qos_key_extract.dpkg,
1532 NET_PROT_IP, NH_FLD_IP_PROTO);
1534 ret = dpaa2_flow_proto_discrimination_extract(
1535 &priv->extract.qos_key_extract,
1536 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1539 "QoS Extract IP protocol to discriminate ICMP failed.");
1543 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1546 index = dpaa2_flow_extract_search(
1547 &priv->extract.tc_key_extract[group].dpkg,
1548 NET_PROT_IP, NH_FLD_IP_PROTO);
1550 ret = dpaa2_flow_proto_discrimination_extract(
1551 &priv->extract.tc_key_extract[group],
1552 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1555 "FS Extract IP protocol to discriminate ICMP failed.");
1559 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1562 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1565 "Move IP addr before ICMP discrimination set failed");
1569 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1570 proto.ip_proto = IPPROTO_ICMP;
1571 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1574 DPAA2_PMD_ERR("ICMP discrimination rule set failed");
1578 (*device_configured) |= local_cfg;
1583 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1584 RTE_FLOW_ITEM_TYPE_ICMP)) {
1585 DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
1590 if (mask->hdr.icmp_type) {
1591 index = dpaa2_flow_extract_search(
1592 &priv->extract.qos_key_extract.dpkg,
1593 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1595 ret = dpaa2_flow_extract_add(
1596 &priv->extract.qos_key_extract,
1599 NH_FLD_ICMP_TYPE_SIZE);
1601 DPAA2_PMD_ERR("QoS Extract add ICMP_TYPE failed.");
1605 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1608 index = dpaa2_flow_extract_search(
1609 &priv->extract.tc_key_extract[group].dpkg,
1610 NET_PROT_ICMP, NH_FLD_ICMP_TYPE);
1612 ret = dpaa2_flow_extract_add(
1613 &priv->extract.tc_key_extract[group],
1616 NH_FLD_ICMP_TYPE_SIZE);
1618 DPAA2_PMD_ERR("FS Extract add ICMP_TYPE failed.");
1622 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1625 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1628 "Move ipaddr before ICMP TYPE set failed");
1632 ret = dpaa2_flow_rule_data_set(
1633 &priv->extract.qos_key_extract,
1637 &spec->hdr.icmp_type,
1638 &mask->hdr.icmp_type,
1639 NH_FLD_ICMP_TYPE_SIZE);
1641 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_TYPE rule data set failed");
1645 ret = dpaa2_flow_rule_data_set(
1646 &priv->extract.tc_key_extract[group],
1650 &spec->hdr.icmp_type,
1651 &mask->hdr.icmp_type,
1652 NH_FLD_ICMP_TYPE_SIZE);
1654 DPAA2_PMD_ERR("FS NH_FLD_ICMP_TYPE rule data set failed");
1659 if (mask->hdr.icmp_code) {
1660 index = dpaa2_flow_extract_search(
1661 &priv->extract.qos_key_extract.dpkg,
1662 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1664 ret = dpaa2_flow_extract_add(
1665 &priv->extract.qos_key_extract,
1668 NH_FLD_ICMP_CODE_SIZE);
1670 DPAA2_PMD_ERR("QoS Extract add ICMP_CODE failed.");
1674 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1677 index = dpaa2_flow_extract_search(
1678 &priv->extract.tc_key_extract[group].dpkg,
1679 NET_PROT_ICMP, NH_FLD_ICMP_CODE);
1681 ret = dpaa2_flow_extract_add(
1682 &priv->extract.tc_key_extract[group],
1685 NH_FLD_ICMP_CODE_SIZE);
1687 DPAA2_PMD_ERR("FS Extract add ICMP_CODE failed.");
1691 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1694 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1697 "Move ipaddr after ICMP CODE set failed");
1701 ret = dpaa2_flow_rule_data_set(
1702 &priv->extract.qos_key_extract,
1706 &spec->hdr.icmp_code,
1707 &mask->hdr.icmp_code,
1708 NH_FLD_ICMP_CODE_SIZE);
1710 DPAA2_PMD_ERR("QoS NH_FLD_ICMP_CODE rule data set failed");
1714 ret = dpaa2_flow_rule_data_set(
1715 &priv->extract.tc_key_extract[group],
1719 &spec->hdr.icmp_code,
1720 &mask->hdr.icmp_code,
1721 NH_FLD_ICMP_CODE_SIZE);
1723 DPAA2_PMD_ERR("FS NH_FLD_ICMP_CODE rule data set failed");
1728 (*device_configured) |= local_cfg;
1734 dpaa2_configure_flow_udp(struct rte_flow *flow,
1735 struct rte_eth_dev *dev,
1736 const struct rte_flow_attr *attr,
1737 const struct rte_flow_item *pattern,
1738 const struct rte_flow_action actions[] __rte_unused,
1739 struct rte_flow_error *error __rte_unused,
1740 int *device_configured)
1745 const struct rte_flow_item_udp *spec, *mask;
1747 const struct rte_flow_item_udp *last __rte_unused;
1748 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1750 group = attr->group;
1752 /* Parse pattern list to get the matching parameters */
1753 spec = (const struct rte_flow_item_udp *)pattern->spec;
1754 last = (const struct rte_flow_item_udp *)pattern->last;
1755 mask = (const struct rte_flow_item_udp *)
1756 (pattern->mask ? pattern->mask : &dpaa2_flow_item_udp_mask);
1758 /* Get traffic class index and flow id to be configured */
1759 flow->tc_id = group;
1760 flow->tc_index = attr->priority;
1762 if (!spec || !mc_l4_port_identification) {
1763 struct proto_discrimination proto;
1765 index = dpaa2_flow_extract_search(
1766 &priv->extract.qos_key_extract.dpkg,
1767 NET_PROT_IP, NH_FLD_IP_PROTO);
1769 ret = dpaa2_flow_proto_discrimination_extract(
1770 &priv->extract.qos_key_extract,
1771 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1774 "QoS Extract IP protocol to discriminate UDP failed.");
1778 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1781 index = dpaa2_flow_extract_search(
1782 &priv->extract.tc_key_extract[group].dpkg,
1783 NET_PROT_IP, NH_FLD_IP_PROTO);
1785 ret = dpaa2_flow_proto_discrimination_extract(
1786 &priv->extract.tc_key_extract[group],
1787 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
1790 "FS Extract IP protocol to discriminate UDP failed.");
1794 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1797 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1800 "Move IP addr before UDP discrimination set failed");
1804 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
1805 proto.ip_proto = IPPROTO_UDP;
1806 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
1809 DPAA2_PMD_ERR("UDP discrimination rule set failed");
1813 (*device_configured) |= local_cfg;
1819 if (dpaa2_flow_extract_support((const uint8_t *)mask,
1820 RTE_FLOW_ITEM_TYPE_UDP)) {
1821 DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
1826 if (mask->hdr.src_port) {
1827 index = dpaa2_flow_extract_search(
1828 &priv->extract.qos_key_extract.dpkg,
1829 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
1831 ret = dpaa2_flow_extract_add(
1832 &priv->extract.qos_key_extract,
1834 NH_FLD_UDP_PORT_SRC,
1835 NH_FLD_UDP_PORT_SIZE);
1837 DPAA2_PMD_ERR("QoS Extract add UDP_SRC failed.");
1841 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1844 index = dpaa2_flow_extract_search(
1845 &priv->extract.tc_key_extract[group].dpkg,
1846 NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
1848 ret = dpaa2_flow_extract_add(
1849 &priv->extract.tc_key_extract[group],
1851 NH_FLD_UDP_PORT_SRC,
1852 NH_FLD_UDP_PORT_SIZE);
1854 DPAA2_PMD_ERR("FS Extract add UDP_SRC failed.");
1858 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1861 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1864 "Move ipaddr before UDP_PORT_SRC set failed");
1868 ret = dpaa2_flow_rule_data_set(&priv->extract.qos_key_extract,
1871 NH_FLD_UDP_PORT_SRC,
1872 &spec->hdr.src_port,
1873 &mask->hdr.src_port,
1874 NH_FLD_UDP_PORT_SIZE);
1877 "QoS NH_FLD_UDP_PORT_SRC rule data set failed");
1881 ret = dpaa2_flow_rule_data_set(
1882 &priv->extract.tc_key_extract[group],
1885 NH_FLD_UDP_PORT_SRC,
1886 &spec->hdr.src_port,
1887 &mask->hdr.src_port,
1888 NH_FLD_UDP_PORT_SIZE);
1891 "FS NH_FLD_UDP_PORT_SRC rule data set failed");
1896 if (mask->hdr.dst_port) {
1897 index = dpaa2_flow_extract_search(
1898 &priv->extract.qos_key_extract.dpkg,
1899 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
1901 ret = dpaa2_flow_extract_add(
1902 &priv->extract.qos_key_extract,
1904 NH_FLD_UDP_PORT_DST,
1905 NH_FLD_UDP_PORT_SIZE);
1907 DPAA2_PMD_ERR("QoS Extract add UDP_DST failed.");
1911 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
1914 index = dpaa2_flow_extract_search(
1915 &priv->extract.tc_key_extract[group].dpkg,
1916 NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
1918 ret = dpaa2_flow_extract_add(
1919 &priv->extract.tc_key_extract[group],
1921 NH_FLD_UDP_PORT_DST,
1922 NH_FLD_UDP_PORT_SIZE);
1924 DPAA2_PMD_ERR("FS Extract add UDP_DST failed.");
1928 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
1931 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
1934 "Move ipaddr before UDP_PORT_DST set failed");
1938 ret = dpaa2_flow_rule_data_set(
1939 &priv->extract.qos_key_extract,
1942 NH_FLD_UDP_PORT_DST,
1943 &spec->hdr.dst_port,
1944 &mask->hdr.dst_port,
1945 NH_FLD_UDP_PORT_SIZE);
1948 "QoS NH_FLD_UDP_PORT_DST rule data set failed");
1952 ret = dpaa2_flow_rule_data_set(
1953 &priv->extract.tc_key_extract[group],
1956 NH_FLD_UDP_PORT_DST,
1957 &spec->hdr.dst_port,
1958 &mask->hdr.dst_port,
1959 NH_FLD_UDP_PORT_SIZE);
1962 "FS NH_FLD_UDP_PORT_DST rule data set failed");
1967 (*device_configured) |= local_cfg;
1973 dpaa2_configure_flow_tcp(struct rte_flow *flow,
1974 struct rte_eth_dev *dev,
1975 const struct rte_flow_attr *attr,
1976 const struct rte_flow_item *pattern,
1977 const struct rte_flow_action actions[] __rte_unused,
1978 struct rte_flow_error *error __rte_unused,
1979 int *device_configured)
1984 const struct rte_flow_item_tcp *spec, *mask;
1986 const struct rte_flow_item_tcp *last __rte_unused;
1987 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1989 group = attr->group;
1991 /* Parse pattern list to get the matching parameters */
1992 spec = (const struct rte_flow_item_tcp *)pattern->spec;
1993 last = (const struct rte_flow_item_tcp *)pattern->last;
1994 mask = (const struct rte_flow_item_tcp *)
1995 (pattern->mask ? pattern->mask : &dpaa2_flow_item_tcp_mask);
1997 /* Get traffic class index and flow id to be configured */
1998 flow->tc_id = group;
1999 flow->tc_index = attr->priority;
2001 if (!spec || !mc_l4_port_identification) {
2002 struct proto_discrimination proto;
2004 index = dpaa2_flow_extract_search(
2005 &priv->extract.qos_key_extract.dpkg,
2006 NET_PROT_IP, NH_FLD_IP_PROTO);
2008 ret = dpaa2_flow_proto_discrimination_extract(
2009 &priv->extract.qos_key_extract,
2010 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2013 "QoS Extract IP protocol to discriminate TCP failed.");
2017 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2020 index = dpaa2_flow_extract_search(
2021 &priv->extract.tc_key_extract[group].dpkg,
2022 NET_PROT_IP, NH_FLD_IP_PROTO);
2024 ret = dpaa2_flow_proto_discrimination_extract(
2025 &priv->extract.tc_key_extract[group],
2026 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2029 "FS Extract IP protocol to discriminate TCP failed.");
2033 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2036 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2039 "Move IP addr before TCP discrimination set failed");
2043 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2044 proto.ip_proto = IPPROTO_TCP;
2045 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2048 DPAA2_PMD_ERR("TCP discrimination rule set failed");
2052 (*device_configured) |= local_cfg;
2058 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2059 RTE_FLOW_ITEM_TYPE_TCP)) {
2060 DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
2065 if (mask->hdr.src_port) {
2066 index = dpaa2_flow_extract_search(
2067 &priv->extract.qos_key_extract.dpkg,
2068 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2070 ret = dpaa2_flow_extract_add(
2071 &priv->extract.qos_key_extract,
2073 NH_FLD_TCP_PORT_SRC,
2074 NH_FLD_TCP_PORT_SIZE);
2076 DPAA2_PMD_ERR("QoS Extract add TCP_SRC failed.");
2080 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2083 index = dpaa2_flow_extract_search(
2084 &priv->extract.tc_key_extract[group].dpkg,
2085 NET_PROT_TCP, NH_FLD_TCP_PORT_SRC);
2087 ret = dpaa2_flow_extract_add(
2088 &priv->extract.tc_key_extract[group],
2090 NH_FLD_TCP_PORT_SRC,
2091 NH_FLD_TCP_PORT_SIZE);
2093 DPAA2_PMD_ERR("FS Extract add TCP_SRC failed.");
2097 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2100 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2103 "Move ipaddr before TCP_PORT_SRC set failed");
2107 ret = dpaa2_flow_rule_data_set(
2108 &priv->extract.qos_key_extract,
2111 NH_FLD_TCP_PORT_SRC,
2112 &spec->hdr.src_port,
2113 &mask->hdr.src_port,
2114 NH_FLD_TCP_PORT_SIZE);
2117 "QoS NH_FLD_TCP_PORT_SRC rule data set failed");
2121 ret = dpaa2_flow_rule_data_set(
2122 &priv->extract.tc_key_extract[group],
2125 NH_FLD_TCP_PORT_SRC,
2126 &spec->hdr.src_port,
2127 &mask->hdr.src_port,
2128 NH_FLD_TCP_PORT_SIZE);
2131 "FS NH_FLD_TCP_PORT_SRC rule data set failed");
2136 if (mask->hdr.dst_port) {
2137 index = dpaa2_flow_extract_search(
2138 &priv->extract.qos_key_extract.dpkg,
2139 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2141 ret = dpaa2_flow_extract_add(
2142 &priv->extract.qos_key_extract,
2144 NH_FLD_TCP_PORT_DST,
2145 NH_FLD_TCP_PORT_SIZE);
2147 DPAA2_PMD_ERR("QoS Extract add TCP_DST failed.");
2151 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2154 index = dpaa2_flow_extract_search(
2155 &priv->extract.tc_key_extract[group].dpkg,
2156 NET_PROT_TCP, NH_FLD_TCP_PORT_DST);
2158 ret = dpaa2_flow_extract_add(
2159 &priv->extract.tc_key_extract[group],
2161 NH_FLD_TCP_PORT_DST,
2162 NH_FLD_TCP_PORT_SIZE);
2164 DPAA2_PMD_ERR("FS Extract add TCP_DST failed.");
2168 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2171 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2174 "Move ipaddr before TCP_PORT_DST set failed");
2178 ret = dpaa2_flow_rule_data_set(
2179 &priv->extract.qos_key_extract,
2182 NH_FLD_TCP_PORT_DST,
2183 &spec->hdr.dst_port,
2184 &mask->hdr.dst_port,
2185 NH_FLD_TCP_PORT_SIZE);
2188 "QoS NH_FLD_TCP_PORT_DST rule data set failed");
2192 ret = dpaa2_flow_rule_data_set(
2193 &priv->extract.tc_key_extract[group],
2196 NH_FLD_TCP_PORT_DST,
2197 &spec->hdr.dst_port,
2198 &mask->hdr.dst_port,
2199 NH_FLD_TCP_PORT_SIZE);
2202 "FS NH_FLD_TCP_PORT_DST rule data set failed");
2207 (*device_configured) |= local_cfg;
2213 dpaa2_configure_flow_sctp(struct rte_flow *flow,
2214 struct rte_eth_dev *dev,
2215 const struct rte_flow_attr *attr,
2216 const struct rte_flow_item *pattern,
2217 const struct rte_flow_action actions[] __rte_unused,
2218 struct rte_flow_error *error __rte_unused,
2219 int *device_configured)
2224 const struct rte_flow_item_sctp *spec, *mask;
2226 const struct rte_flow_item_sctp *last __rte_unused;
2227 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2229 group = attr->group;
2231 /* Parse pattern list to get the matching parameters */
2232 spec = (const struct rte_flow_item_sctp *)pattern->spec;
2233 last = (const struct rte_flow_item_sctp *)pattern->last;
2234 mask = (const struct rte_flow_item_sctp *)
2235 (pattern->mask ? pattern->mask :
2236 &dpaa2_flow_item_sctp_mask);
2238 /* Get traffic class index and flow id to be configured */
2239 flow->tc_id = group;
2240 flow->tc_index = attr->priority;
2242 if (!spec || !mc_l4_port_identification) {
2243 struct proto_discrimination proto;
2245 index = dpaa2_flow_extract_search(
2246 &priv->extract.qos_key_extract.dpkg,
2247 NET_PROT_IP, NH_FLD_IP_PROTO);
2249 ret = dpaa2_flow_proto_discrimination_extract(
2250 &priv->extract.qos_key_extract,
2251 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2254 "QoS Extract IP protocol to discriminate SCTP failed.");
2258 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2261 index = dpaa2_flow_extract_search(
2262 &priv->extract.tc_key_extract[group].dpkg,
2263 NET_PROT_IP, NH_FLD_IP_PROTO);
2265 ret = dpaa2_flow_proto_discrimination_extract(
2266 &priv->extract.tc_key_extract[group],
2267 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2270 "FS Extract IP protocol to discriminate SCTP failed.");
2274 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2277 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2280 "Move ipaddr before SCTP discrimination set failed");
2284 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2285 proto.ip_proto = IPPROTO_SCTP;
2286 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2289 DPAA2_PMD_ERR("SCTP discrimination rule set failed");
2293 (*device_configured) |= local_cfg;
2299 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2300 RTE_FLOW_ITEM_TYPE_SCTP)) {
2301 DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
2306 if (mask->hdr.src_port) {
2307 index = dpaa2_flow_extract_search(
2308 &priv->extract.qos_key_extract.dpkg,
2309 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2311 ret = dpaa2_flow_extract_add(
2312 &priv->extract.qos_key_extract,
2314 NH_FLD_SCTP_PORT_SRC,
2315 NH_FLD_SCTP_PORT_SIZE);
2317 DPAA2_PMD_ERR("QoS Extract add SCTP_SRC failed.");
2321 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2324 index = dpaa2_flow_extract_search(
2325 &priv->extract.tc_key_extract[group].dpkg,
2326 NET_PROT_SCTP, NH_FLD_SCTP_PORT_SRC);
2328 ret = dpaa2_flow_extract_add(
2329 &priv->extract.tc_key_extract[group],
2331 NH_FLD_SCTP_PORT_SRC,
2332 NH_FLD_SCTP_PORT_SIZE);
2334 DPAA2_PMD_ERR("FS Extract add SCTP_SRC failed.");
2338 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2341 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2344 "Move ipaddr before SCTP_PORT_SRC set failed");
2348 ret = dpaa2_flow_rule_data_set(
2349 &priv->extract.qos_key_extract,
2352 NH_FLD_SCTP_PORT_SRC,
2353 &spec->hdr.src_port,
2354 &mask->hdr.src_port,
2355 NH_FLD_SCTP_PORT_SIZE);
2358 "QoS NH_FLD_SCTP_PORT_SRC rule data set failed");
2362 ret = dpaa2_flow_rule_data_set(
2363 &priv->extract.tc_key_extract[group],
2366 NH_FLD_SCTP_PORT_SRC,
2367 &spec->hdr.src_port,
2368 &mask->hdr.src_port,
2369 NH_FLD_SCTP_PORT_SIZE);
2372 "FS NH_FLD_SCTP_PORT_SRC rule data set failed");
2377 if (mask->hdr.dst_port) {
2378 index = dpaa2_flow_extract_search(
2379 &priv->extract.qos_key_extract.dpkg,
2380 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2382 ret = dpaa2_flow_extract_add(
2383 &priv->extract.qos_key_extract,
2385 NH_FLD_SCTP_PORT_DST,
2386 NH_FLD_SCTP_PORT_SIZE);
2388 DPAA2_PMD_ERR("QoS Extract add SCTP_DST failed.");
2392 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2395 index = dpaa2_flow_extract_search(
2396 &priv->extract.tc_key_extract[group].dpkg,
2397 NET_PROT_SCTP, NH_FLD_SCTP_PORT_DST);
2399 ret = dpaa2_flow_extract_add(
2400 &priv->extract.tc_key_extract[group],
2402 NH_FLD_SCTP_PORT_DST,
2403 NH_FLD_SCTP_PORT_SIZE);
2405 DPAA2_PMD_ERR("FS Extract add SCTP_DST failed.");
2409 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2412 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2415 "Move ipaddr before SCTP_PORT_DST set failed");
2419 ret = dpaa2_flow_rule_data_set(
2420 &priv->extract.qos_key_extract,
2423 NH_FLD_SCTP_PORT_DST,
2424 &spec->hdr.dst_port,
2425 &mask->hdr.dst_port,
2426 NH_FLD_SCTP_PORT_SIZE);
2429 "QoS NH_FLD_SCTP_PORT_DST rule data set failed");
2433 ret = dpaa2_flow_rule_data_set(
2434 &priv->extract.tc_key_extract[group],
2437 NH_FLD_SCTP_PORT_DST,
2438 &spec->hdr.dst_port,
2439 &mask->hdr.dst_port,
2440 NH_FLD_SCTP_PORT_SIZE);
2443 "FS NH_FLD_SCTP_PORT_DST rule data set failed");
2448 (*device_configured) |= local_cfg;
2454 dpaa2_configure_flow_gre(struct rte_flow *flow,
2455 struct rte_eth_dev *dev,
2456 const struct rte_flow_attr *attr,
2457 const struct rte_flow_item *pattern,
2458 const struct rte_flow_action actions[] __rte_unused,
2459 struct rte_flow_error *error __rte_unused,
2460 int *device_configured)
2465 const struct rte_flow_item_gre *spec, *mask;
2467 const struct rte_flow_item_gre *last __rte_unused;
2468 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2470 group = attr->group;
2472 /* Parse pattern list to get the matching parameters */
2473 spec = (const struct rte_flow_item_gre *)pattern->spec;
2474 last = (const struct rte_flow_item_gre *)pattern->last;
2475 mask = (const struct rte_flow_item_gre *)
2476 (pattern->mask ? pattern->mask : &dpaa2_flow_item_gre_mask);
2478 /* Get traffic class index and flow id to be configured */
2479 flow->tc_id = group;
2480 flow->tc_index = attr->priority;
2483 struct proto_discrimination proto;
2485 index = dpaa2_flow_extract_search(
2486 &priv->extract.qos_key_extract.dpkg,
2487 NET_PROT_IP, NH_FLD_IP_PROTO);
2489 ret = dpaa2_flow_proto_discrimination_extract(
2490 &priv->extract.qos_key_extract,
2491 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2494 "QoS Extract IP protocol to discriminate GRE failed.");
2498 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2501 index = dpaa2_flow_extract_search(
2502 &priv->extract.tc_key_extract[group].dpkg,
2503 NET_PROT_IP, NH_FLD_IP_PROTO);
2505 ret = dpaa2_flow_proto_discrimination_extract(
2506 &priv->extract.tc_key_extract[group],
2507 DPAA2_FLOW_ITEM_TYPE_GENERIC_IP);
2510 "FS Extract IP protocol to discriminate GRE failed.");
2514 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2517 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2520 "Move IP addr before GRE discrimination set failed");
2524 proto.type = DPAA2_FLOW_ITEM_TYPE_GENERIC_IP;
2525 proto.ip_proto = IPPROTO_GRE;
2526 ret = dpaa2_flow_proto_discrimination_rule(priv, flow,
2529 DPAA2_PMD_ERR("GRE discrimination rule set failed");
2533 (*device_configured) |= local_cfg;
2538 if (dpaa2_flow_extract_support((const uint8_t *)mask,
2539 RTE_FLOW_ITEM_TYPE_GRE)) {
2540 DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
2545 if (!mask->protocol)
2548 index = dpaa2_flow_extract_search(
2549 &priv->extract.qos_key_extract.dpkg,
2550 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2552 ret = dpaa2_flow_extract_add(
2553 &priv->extract.qos_key_extract,
2556 sizeof(rte_be16_t));
2558 DPAA2_PMD_ERR("QoS Extract add GRE_TYPE failed.");
2562 local_cfg |= DPAA2_QOS_TABLE_RECONFIGURE;
2565 index = dpaa2_flow_extract_search(
2566 &priv->extract.tc_key_extract[group].dpkg,
2567 NET_PROT_GRE, NH_FLD_GRE_TYPE);
2569 ret = dpaa2_flow_extract_add(
2570 &priv->extract.tc_key_extract[group],
2573 sizeof(rte_be16_t));
2575 DPAA2_PMD_ERR("FS Extract add GRE_TYPE failed.");
2579 local_cfg |= DPAA2_FS_TABLE_RECONFIGURE;
2582 ret = dpaa2_flow_rule_move_ipaddr_tail(flow, priv, group);
2585 "Move ipaddr before GRE_TYPE set failed");
2589 ret = dpaa2_flow_rule_data_set(
2590 &priv->extract.qos_key_extract,
2596 sizeof(rte_be16_t));
2599 "QoS NH_FLD_GRE_TYPE rule data set failed");
2603 ret = dpaa2_flow_rule_data_set(
2604 &priv->extract.tc_key_extract[group],
2610 sizeof(rte_be16_t));
2613 "FS NH_FLD_GRE_TYPE rule data set failed");
2617 (*device_configured) |= local_cfg;
2622 /* The existing QoS/FS entry with IP address(es)
2623 * needs update after
2624 * new extract(s) are inserted before IP
2625 * address(es) extract(s).
2628 dpaa2_flow_entry_update(
2629 struct dpaa2_dev_priv *priv, uint8_t tc_id)
2631 struct rte_flow *curr = LIST_FIRST(&priv->flows);
2632 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
2634 int qos_ipsrc_offset = -1, qos_ipdst_offset = -1;
2635 int fs_ipsrc_offset = -1, fs_ipdst_offset = -1;
2636 struct dpaa2_key_extract *qos_key_extract =
2637 &priv->extract.qos_key_extract;
2638 struct dpaa2_key_extract *tc_key_extract =
2639 &priv->extract.tc_key_extract[tc_id];
2640 char ipsrc_key[NH_FLD_IPV6_ADDR_SIZE];
2641 char ipdst_key[NH_FLD_IPV6_ADDR_SIZE];
2642 char ipsrc_mask[NH_FLD_IPV6_ADDR_SIZE];
2643 char ipdst_mask[NH_FLD_IPV6_ADDR_SIZE];
2644 int extend = -1, extend1, size;
2648 if (curr->ipaddr_rule.ipaddr_type ==
2650 curr = LIST_NEXT(curr, next);
2654 if (curr->ipaddr_rule.ipaddr_type ==
2657 qos_key_extract->key_info.ipv4_src_offset;
2659 qos_key_extract->key_info.ipv4_dst_offset;
2661 tc_key_extract->key_info.ipv4_src_offset;
2663 tc_key_extract->key_info.ipv4_dst_offset;
2664 size = NH_FLD_IPV4_ADDR_SIZE;
2667 qos_key_extract->key_info.ipv6_src_offset;
2669 qos_key_extract->key_info.ipv6_dst_offset;
2671 tc_key_extract->key_info.ipv6_src_offset;
2673 tc_key_extract->key_info.ipv6_dst_offset;
2674 size = NH_FLD_IPV6_ADDR_SIZE;
2677 qos_index = curr->tc_id * priv->fs_entries +
2680 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
2681 priv->token, &curr->qos_rule);
2683 DPAA2_PMD_ERR("Qos entry remove failed.");
2689 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2690 RTE_ASSERT(qos_ipsrc_offset >=
2691 curr->ipaddr_rule.qos_ipsrc_offset);
2692 extend1 = qos_ipsrc_offset -
2693 curr->ipaddr_rule.qos_ipsrc_offset;
2695 RTE_ASSERT(extend == extend1);
2700 (char *)(size_t)curr->qos_rule.key_iova +
2701 curr->ipaddr_rule.qos_ipsrc_offset,
2703 memset((char *)(size_t)curr->qos_rule.key_iova +
2704 curr->ipaddr_rule.qos_ipsrc_offset,
2708 (char *)(size_t)curr->qos_rule.mask_iova +
2709 curr->ipaddr_rule.qos_ipsrc_offset,
2711 memset((char *)(size_t)curr->qos_rule.mask_iova +
2712 curr->ipaddr_rule.qos_ipsrc_offset,
2715 curr->ipaddr_rule.qos_ipsrc_offset = qos_ipsrc_offset;
2718 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2719 RTE_ASSERT(qos_ipdst_offset >=
2720 curr->ipaddr_rule.qos_ipdst_offset);
2721 extend1 = qos_ipdst_offset -
2722 curr->ipaddr_rule.qos_ipdst_offset;
2724 RTE_ASSERT(extend == extend1);
2729 (char *)(size_t)curr->qos_rule.key_iova +
2730 curr->ipaddr_rule.qos_ipdst_offset,
2732 memset((char *)(size_t)curr->qos_rule.key_iova +
2733 curr->ipaddr_rule.qos_ipdst_offset,
2737 (char *)(size_t)curr->qos_rule.mask_iova +
2738 curr->ipaddr_rule.qos_ipdst_offset,
2740 memset((char *)(size_t)curr->qos_rule.mask_iova +
2741 curr->ipaddr_rule.qos_ipdst_offset,
2744 curr->ipaddr_rule.qos_ipdst_offset = qos_ipdst_offset;
2747 if (curr->ipaddr_rule.qos_ipsrc_offset >= 0) {
2748 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2749 curr->ipaddr_rule.qos_ipsrc_offset,
2752 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2753 curr->ipaddr_rule.qos_ipsrc_offset,
2757 if (curr->ipaddr_rule.qos_ipdst_offset >= 0) {
2758 memcpy((char *)(size_t)curr->qos_rule.key_iova +
2759 curr->ipaddr_rule.qos_ipdst_offset,
2762 memcpy((char *)(size_t)curr->qos_rule.mask_iova +
2763 curr->ipaddr_rule.qos_ipdst_offset,
2769 curr->qos_rule.key_size += extend;
2771 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
2772 priv->token, &curr->qos_rule,
2773 curr->tc_id, qos_index,
2776 DPAA2_PMD_ERR("Qos entry update failed.");
2780 if (curr->action != RTE_FLOW_ACTION_TYPE_QUEUE) {
2781 curr = LIST_NEXT(curr, next);
2787 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW,
2788 priv->token, curr->tc_id, &curr->fs_rule);
2790 DPAA2_PMD_ERR("FS entry remove failed.");
2794 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0 &&
2795 tc_id == curr->tc_id) {
2796 RTE_ASSERT(fs_ipsrc_offset >=
2797 curr->ipaddr_rule.fs_ipsrc_offset);
2798 extend1 = fs_ipsrc_offset -
2799 curr->ipaddr_rule.fs_ipsrc_offset;
2801 RTE_ASSERT(extend == extend1);
2806 (char *)(size_t)curr->fs_rule.key_iova +
2807 curr->ipaddr_rule.fs_ipsrc_offset,
2809 memset((char *)(size_t)curr->fs_rule.key_iova +
2810 curr->ipaddr_rule.fs_ipsrc_offset,
2814 (char *)(size_t)curr->fs_rule.mask_iova +
2815 curr->ipaddr_rule.fs_ipsrc_offset,
2817 memset((char *)(size_t)curr->fs_rule.mask_iova +
2818 curr->ipaddr_rule.fs_ipsrc_offset,
2821 curr->ipaddr_rule.fs_ipsrc_offset = fs_ipsrc_offset;
2824 if (curr->ipaddr_rule.fs_ipdst_offset >= 0 &&
2825 tc_id == curr->tc_id) {
2826 RTE_ASSERT(fs_ipdst_offset >=
2827 curr->ipaddr_rule.fs_ipdst_offset);
2828 extend1 = fs_ipdst_offset -
2829 curr->ipaddr_rule.fs_ipdst_offset;
2831 RTE_ASSERT(extend == extend1);
2836 (char *)(size_t)curr->fs_rule.key_iova +
2837 curr->ipaddr_rule.fs_ipdst_offset,
2839 memset((char *)(size_t)curr->fs_rule.key_iova +
2840 curr->ipaddr_rule.fs_ipdst_offset,
2844 (char *)(size_t)curr->fs_rule.mask_iova +
2845 curr->ipaddr_rule.fs_ipdst_offset,
2847 memset((char *)(size_t)curr->fs_rule.mask_iova +
2848 curr->ipaddr_rule.fs_ipdst_offset,
2851 curr->ipaddr_rule.fs_ipdst_offset = fs_ipdst_offset;
2854 if (curr->ipaddr_rule.fs_ipsrc_offset >= 0) {
2855 memcpy((char *)(size_t)curr->fs_rule.key_iova +
2856 curr->ipaddr_rule.fs_ipsrc_offset,
2859 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
2860 curr->ipaddr_rule.fs_ipsrc_offset,
2864 if (curr->ipaddr_rule.fs_ipdst_offset >= 0) {
2865 memcpy((char *)(size_t)curr->fs_rule.key_iova +
2866 curr->ipaddr_rule.fs_ipdst_offset,
2869 memcpy((char *)(size_t)curr->fs_rule.mask_iova +
2870 curr->ipaddr_rule.fs_ipdst_offset,
2876 curr->fs_rule.key_size += extend;
2878 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
2879 priv->token, curr->tc_id, curr->tc_index,
2880 &curr->fs_rule, &curr->action_cfg);
2882 DPAA2_PMD_ERR("FS entry update failed.");
2886 curr = LIST_NEXT(curr, next);
2893 dpaa2_flow_verify_attr(
2894 struct dpaa2_dev_priv *priv,
2895 const struct rte_flow_attr *attr)
2897 struct rte_flow *curr = LIST_FIRST(&priv->flows);
2900 if (curr->tc_id == attr->group &&
2901 curr->tc_index == attr->priority) {
2903 "Flow with group %d and priority %d already exists.",
2904 attr->group, attr->priority);
2908 curr = LIST_NEXT(curr, next);
2915 dpaa2_generic_flow_set(struct rte_flow *flow,
2916 struct rte_eth_dev *dev,
2917 const struct rte_flow_attr *attr,
2918 const struct rte_flow_item pattern[],
2919 const struct rte_flow_action actions[],
2920 struct rte_flow_error *error)
2922 const struct rte_flow_action_queue *dest_queue;
2923 const struct rte_flow_action_rss *rss_conf;
2924 int is_keycfg_configured = 0, end_of_list = 0;
2925 int ret = 0, i = 0, j = 0;
2926 struct dpni_rx_tc_dist_cfg tc_cfg;
2927 struct dpni_qos_tbl_cfg qos_cfg;
2928 struct dpni_fs_action_cfg action;
2929 struct dpaa2_dev_priv *priv = dev->data->dev_private;
2930 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
2932 struct rte_flow *curr = LIST_FIRST(&priv->flows);
2935 ret = dpaa2_flow_verify_attr(priv, attr);
2939 /* Parse pattern list to get the matching parameters */
2940 while (!end_of_list) {
2941 switch (pattern[i].type) {
2942 case RTE_FLOW_ITEM_TYPE_ETH:
2943 ret = dpaa2_configure_flow_eth(flow,
2944 dev, attr, &pattern[i], actions, error,
2945 &is_keycfg_configured);
2947 DPAA2_PMD_ERR("ETH flow configuration failed!");
2951 case RTE_FLOW_ITEM_TYPE_VLAN:
2952 ret = dpaa2_configure_flow_vlan(flow,
2953 dev, attr, &pattern[i], actions, error,
2954 &is_keycfg_configured);
2956 DPAA2_PMD_ERR("vLan flow configuration failed!");
2960 case RTE_FLOW_ITEM_TYPE_IPV4:
2961 case RTE_FLOW_ITEM_TYPE_IPV6:
2962 ret = dpaa2_configure_flow_generic_ip(flow,
2963 dev, attr, &pattern[i], actions, error,
2964 &is_keycfg_configured);
2966 DPAA2_PMD_ERR("IP flow configuration failed!");
2970 case RTE_FLOW_ITEM_TYPE_ICMP:
2971 ret = dpaa2_configure_flow_icmp(flow,
2972 dev, attr, &pattern[i], actions, error,
2973 &is_keycfg_configured);
2975 DPAA2_PMD_ERR("ICMP flow configuration failed!");
2979 case RTE_FLOW_ITEM_TYPE_UDP:
2980 ret = dpaa2_configure_flow_udp(flow,
2981 dev, attr, &pattern[i], actions, error,
2982 &is_keycfg_configured);
2984 DPAA2_PMD_ERR("UDP flow configuration failed!");
2988 case RTE_FLOW_ITEM_TYPE_TCP:
2989 ret = dpaa2_configure_flow_tcp(flow,
2990 dev, attr, &pattern[i], actions, error,
2991 &is_keycfg_configured);
2993 DPAA2_PMD_ERR("TCP flow configuration failed!");
2997 case RTE_FLOW_ITEM_TYPE_SCTP:
2998 ret = dpaa2_configure_flow_sctp(flow,
2999 dev, attr, &pattern[i], actions, error,
3000 &is_keycfg_configured);
3002 DPAA2_PMD_ERR("SCTP flow configuration failed!");
3006 case RTE_FLOW_ITEM_TYPE_GRE:
3007 ret = dpaa2_configure_flow_gre(flow,
3008 dev, attr, &pattern[i], actions, error,
3009 &is_keycfg_configured);
3011 DPAA2_PMD_ERR("GRE flow configuration failed!");
3015 case RTE_FLOW_ITEM_TYPE_END:
3017 break; /*End of List*/
3019 DPAA2_PMD_ERR("Invalid action type");
3026 /* Let's parse action on matching traffic */
3028 while (!end_of_list) {
3029 switch (actions[j].type) {
3030 case RTE_FLOW_ACTION_TYPE_QUEUE:
3031 dest_queue = (const struct rte_flow_action_queue *)(actions[j].conf);
3032 flow->flow_id = dest_queue->index;
3033 flow->action = RTE_FLOW_ACTION_TYPE_QUEUE;
3034 memset(&action, 0, sizeof(struct dpni_fs_action_cfg));
3035 action.flow_id = flow->flow_id;
3036 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3037 if (dpkg_prepare_key_cfg(&priv->extract.qos_key_extract.dpkg,
3038 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3040 "Unable to prepare extract parameters");
3044 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
3045 qos_cfg.discard_on_miss = true;
3046 qos_cfg.keep_entries = true;
3047 qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param;
3048 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3049 priv->token, &qos_cfg);
3052 "Distribution cannot be configured.(%d)"
3057 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) {
3058 if (dpkg_prepare_key_cfg(
3059 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3060 (uint8_t *)(size_t)priv->extract
3061 .tc_extract_param[flow->tc_id]) < 0) {
3063 "Unable to prepare extract parameters");
3067 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3068 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc;
3069 tc_cfg.dist_mode = DPNI_DIST_MODE_FS;
3070 tc_cfg.key_cfg_iova =
3071 (uint64_t)priv->extract.tc_extract_param[flow->tc_id];
3072 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3073 tc_cfg.fs_cfg.keep_entries = true;
3074 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3076 flow->tc_id, &tc_cfg);
3079 "Distribution cannot be configured.(%d)"
3084 /* Configure QoS table first */
3086 action.flow_id = action.flow_id % priv->num_rx_tc;
3088 qos_index = flow->tc_id * priv->fs_entries +
3091 if (qos_index >= priv->qos_entries) {
3092 DPAA2_PMD_ERR("QoS table with %d entries full",
3096 flow->qos_rule.key_size = priv->extract
3097 .qos_key_extract.key_info.key_total_size;
3098 if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV4_ADDR) {
3099 if (flow->ipaddr_rule.qos_ipdst_offset >=
3100 flow->ipaddr_rule.qos_ipsrc_offset) {
3101 flow->qos_rule.key_size =
3102 flow->ipaddr_rule.qos_ipdst_offset +
3103 NH_FLD_IPV4_ADDR_SIZE;
3105 flow->qos_rule.key_size =
3106 flow->ipaddr_rule.qos_ipsrc_offset +
3107 NH_FLD_IPV4_ADDR_SIZE;
3109 } else if (flow->ipaddr_rule.ipaddr_type == FLOW_IPV6_ADDR) {
3110 if (flow->ipaddr_rule.qos_ipdst_offset >=
3111 flow->ipaddr_rule.qos_ipsrc_offset) {
3112 flow->qos_rule.key_size =
3113 flow->ipaddr_rule.qos_ipdst_offset +
3114 NH_FLD_IPV6_ADDR_SIZE;
3116 flow->qos_rule.key_size =
3117 flow->ipaddr_rule.qos_ipsrc_offset +
3118 NH_FLD_IPV6_ADDR_SIZE;
3121 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
3122 priv->token, &flow->qos_rule,
3123 flow->tc_id, qos_index,
3127 "Error in addnig entry to QoS table(%d)", ret);
3131 /* Then Configure FS table */
3132 if (flow->tc_index >= priv->fs_entries) {
3133 DPAA2_PMD_ERR("FS table with %d entries full",
3137 flow->fs_rule.key_size = priv->extract
3138 .tc_key_extract[attr->group].key_info.key_total_size;
3139 if (flow->ipaddr_rule.ipaddr_type ==
3141 if (flow->ipaddr_rule.fs_ipdst_offset >=
3142 flow->ipaddr_rule.fs_ipsrc_offset) {
3143 flow->fs_rule.key_size =
3144 flow->ipaddr_rule.fs_ipdst_offset +
3145 NH_FLD_IPV4_ADDR_SIZE;
3147 flow->fs_rule.key_size =
3148 flow->ipaddr_rule.fs_ipsrc_offset +
3149 NH_FLD_IPV4_ADDR_SIZE;
3151 } else if (flow->ipaddr_rule.ipaddr_type ==
3153 if (flow->ipaddr_rule.fs_ipdst_offset >=
3154 flow->ipaddr_rule.fs_ipsrc_offset) {
3155 flow->fs_rule.key_size =
3156 flow->ipaddr_rule.fs_ipdst_offset +
3157 NH_FLD_IPV6_ADDR_SIZE;
3159 flow->fs_rule.key_size =
3160 flow->ipaddr_rule.fs_ipsrc_offset +
3161 NH_FLD_IPV6_ADDR_SIZE;
3164 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3165 flow->tc_id, flow->tc_index,
3166 &flow->fs_rule, &action);
3169 "Error in adding entry to FS table(%d)", ret);
3172 memcpy(&flow->action_cfg, &action,
3173 sizeof(struct dpni_fs_action_cfg));
3175 case RTE_FLOW_ACTION_TYPE_RSS:
3176 rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf);
3177 for (i = 0; i < (int)rss_conf->queue_num; i++) {
3178 if (rss_conf->queue[i] <
3179 (attr->group * priv->dist_queues) ||
3180 rss_conf->queue[i] >=
3181 ((attr->group + 1) * priv->dist_queues)) {
3183 "Queue/Group combination are not supported\n");
3188 flow->action = RTE_FLOW_ACTION_TYPE_RSS;
3189 ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
3190 &priv->extract.tc_key_extract[flow->tc_id].dpkg);
3193 "unable to set flow distribution.please check queue config\n");
3197 /* Allocate DMA'ble memory to write the rules */
3198 param = (size_t)rte_malloc(NULL, 256, 64);
3200 DPAA2_PMD_ERR("Memory allocation failure\n");
3204 if (dpkg_prepare_key_cfg(
3205 &priv->extract.tc_key_extract[flow->tc_id].dpkg,
3206 (uint8_t *)param) < 0) {
3208 "Unable to prepare extract parameters");
3209 rte_free((void *)param);
3213 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
3214 tc_cfg.dist_size = rss_conf->queue_num;
3215 tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
3216 tc_cfg.key_cfg_iova = (size_t)param;
3217 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP;
3219 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW,
3220 priv->token, flow->tc_id,
3224 "Distribution cannot be configured: %d\n", ret);
3225 rte_free((void *)param);
3229 rte_free((void *)param);
3230 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) {
3231 if (dpkg_prepare_key_cfg(
3232 &priv->extract.qos_key_extract.dpkg,
3233 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) {
3235 "Unable to prepare extract parameters");
3239 sizeof(struct dpni_qos_tbl_cfg));
3240 qos_cfg.discard_on_miss = true;
3241 qos_cfg.keep_entries = true;
3242 qos_cfg.key_cfg_iova =
3243 (size_t)priv->extract.qos_extract_param;
3244 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
3245 priv->token, &qos_cfg);
3248 "Distribution can't be configured %d\n",
3254 /* Add Rule into QoS table */
3255 qos_index = flow->tc_id * priv->fs_entries +
3257 if (qos_index >= priv->qos_entries) {
3258 DPAA2_PMD_ERR("QoS table with %d entries full",
3262 flow->qos_rule.key_size =
3263 priv->extract.qos_key_extract.key_info.key_total_size;
3264 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3265 &flow->qos_rule, flow->tc_id,
3269 "Error in entry addition in QoS table(%d)",
3274 case RTE_FLOW_ACTION_TYPE_END:
3278 DPAA2_PMD_ERR("Invalid action type");
3286 ret = dpaa2_flow_entry_update(priv, flow->tc_id);
3288 DPAA2_PMD_ERR("Flow entry update failed.");
3292 /* New rules are inserted. */
3294 LIST_INSERT_HEAD(&priv->flows, flow, next);
3296 while (LIST_NEXT(curr, next))
3297 curr = LIST_NEXT(curr, next);
3298 LIST_INSERT_AFTER(curr, flow, next);
3305 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
3306 const struct rte_flow_attr *attr)
3310 if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
3311 DPAA2_PMD_ERR("Priority group is out of range\n");
3314 if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
3315 DPAA2_PMD_ERR("Priority within the group is out of range\n");
3318 if (unlikely(attr->egress)) {
3320 "Flow configuration is not supported on egress side\n");
3323 if (unlikely(!attr->ingress)) {
3324 DPAA2_PMD_ERR("Ingress flag must be configured\n");
3331 dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
3333 unsigned int i, j, is_found = 0;
3336 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3337 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) {
3338 if (dpaa2_supported_pattern_type[i]
3339 == pattern[j].type) {
3349 /* Lets verify other combinations of given pattern rules */
3350 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
3351 if (!pattern[j].spec) {
3361 dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
3363 unsigned int i, j, is_found = 0;
3366 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3367 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
3368 if (dpaa2_supported_action_type[i] == actions[j].type) {
3378 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
3379 if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
3387 int dpaa2_flow_validate(struct rte_eth_dev *dev,
3388 const struct rte_flow_attr *flow_attr,
3389 const struct rte_flow_item pattern[],
3390 const struct rte_flow_action actions[],
3391 struct rte_flow_error *error)
3393 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3394 struct dpni_attr dpni_attr;
3395 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3396 uint16_t token = priv->token;
3399 memset(&dpni_attr, 0, sizeof(struct dpni_attr));
3400 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
3403 "Failure to get dpni@%p attribute, err code %d\n",
3405 rte_flow_error_set(error, EPERM,
3406 RTE_FLOW_ERROR_TYPE_ATTR,
3407 flow_attr, "invalid");
3411 /* Verify input attributes */
3412 ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
3415 "Invalid attributes are given\n");
3416 rte_flow_error_set(error, EPERM,
3417 RTE_FLOW_ERROR_TYPE_ATTR,
3418 flow_attr, "invalid");
3419 goto not_valid_params;
3421 /* Verify input pattern list */
3422 ret = dpaa2_dev_verify_patterns(pattern);
3425 "Invalid pattern list is given\n");
3426 rte_flow_error_set(error, EPERM,
3427 RTE_FLOW_ERROR_TYPE_ITEM,
3428 pattern, "invalid");
3429 goto not_valid_params;
3431 /* Verify input action list */
3432 ret = dpaa2_dev_verify_actions(actions);
3435 "Invalid action list is given\n");
3436 rte_flow_error_set(error, EPERM,
3437 RTE_FLOW_ERROR_TYPE_ACTION,
3438 actions, "invalid");
3439 goto not_valid_params;
3446 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev,
3447 const struct rte_flow_attr *attr,
3448 const struct rte_flow_item pattern[],
3449 const struct rte_flow_action actions[],
3450 struct rte_flow_error *error)
3452 struct rte_flow *flow = NULL;
3453 size_t key_iova = 0, mask_iova = 0;
3456 flow = rte_zmalloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE);
3458 DPAA2_PMD_ERR("Failure to allocate memory for flow");
3461 /* Allocate DMA'ble memory to write the rules */
3462 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3465 "Memory allocation failure for rule configuration\n");
3468 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3471 "Memory allocation failure for rule configuration\n");
3475 flow->qos_rule.key_iova = key_iova;
3476 flow->qos_rule.mask_iova = mask_iova;
3478 /* Allocate DMA'ble memory to write the rules */
3479 key_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3482 "Memory allocation failure for rule configuration\n");
3485 mask_iova = (size_t)rte_zmalloc(NULL, 256, 64);
3488 "Memory allocation failure for rule configuration\n");
3492 flow->fs_rule.key_iova = key_iova;
3493 flow->fs_rule.mask_iova = mask_iova;
3495 flow->ipaddr_rule.ipaddr_type = FLOW_NONE_IPADDR;
3496 flow->ipaddr_rule.qos_ipsrc_offset =
3497 IP_ADDRESS_OFFSET_INVALID;
3498 flow->ipaddr_rule.qos_ipdst_offset =
3499 IP_ADDRESS_OFFSET_INVALID;
3500 flow->ipaddr_rule.fs_ipsrc_offset =
3501 IP_ADDRESS_OFFSET_INVALID;
3502 flow->ipaddr_rule.fs_ipdst_offset =
3503 IP_ADDRESS_OFFSET_INVALID;
3505 switch (dpaa2_filter_type) {
3506 case RTE_ETH_FILTER_GENERIC:
3507 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern,
3510 if (error->type > RTE_FLOW_ERROR_TYPE_ACTION)
3511 rte_flow_error_set(error, EPERM,
3512 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3515 "Failure to create flow, return code (%d)", ret);
3516 goto creation_error;
3520 DPAA2_PMD_ERR("Filter type (%d) not supported",
3527 rte_flow_error_set(error, EPERM,
3528 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3529 NULL, "memory alloc");
3531 rte_free((void *)flow);
3532 rte_free((void *)key_iova);
3533 rte_free((void *)mask_iova);
3539 int dpaa2_flow_destroy(struct rte_eth_dev *dev,
3540 struct rte_flow *flow,
3541 struct rte_flow_error *error)
3544 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3545 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
3547 switch (flow->action) {
3548 case RTE_FLOW_ACTION_TYPE_QUEUE:
3549 /* Remove entry from QoS table first */
3550 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3554 "Error in adding entry to QoS table(%d)", ret);
3558 /* Then remove entry from FS table */
3559 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
3560 flow->tc_id, &flow->fs_rule);
3563 "Error in entry addition in FS table(%d)", ret);
3567 case RTE_FLOW_ACTION_TYPE_RSS:
3568 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token,
3572 "Error in entry addition in QoS table(%d)", ret);
3578 "Action type (%d) is not supported", flow->action);
3583 LIST_REMOVE(flow, next);
3584 rte_free((void *)(size_t)flow->qos_rule.key_iova);
3585 rte_free((void *)(size_t)flow->qos_rule.mask_iova);
3586 rte_free((void *)(size_t)flow->fs_rule.key_iova);
3587 rte_free((void *)(size_t)flow->fs_rule.mask_iova);
3588 /* Now free the flow */
3593 rte_flow_error_set(error, EPERM,
3594 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
3600 * Destroy user-configured flow rules.
3602 * This function skips internal flows rules.
3604 * @see rte_flow_flush()
3608 dpaa2_flow_flush(struct rte_eth_dev *dev,
3609 struct rte_flow_error *error)
3611 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3612 struct rte_flow *flow = LIST_FIRST(&priv->flows);
3615 struct rte_flow *next = LIST_NEXT(flow, next);
3617 dpaa2_flow_destroy(dev, flow, error);
3624 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
3625 struct rte_flow *flow __rte_unused,
3626 const struct rte_flow_action *actions __rte_unused,
3627 void *data __rte_unused,
3628 struct rte_flow_error *error __rte_unused)
3634 * Clean up all flow rules.
3636 * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
3637 * rules regardless of whether they are internal or user-configured.
3640 * Pointer to private structure.
3643 dpaa2_flow_clean(struct rte_eth_dev *dev)
3645 struct rte_flow *flow;
3646 struct dpaa2_dev_priv *priv = dev->data->dev_private;
3648 while ((flow = LIST_FIRST(&priv->flows)))
3649 dpaa2_flow_destroy(dev, flow, NULL);
3652 const struct rte_flow_ops dpaa2_flow_ops = {
3653 .create = dpaa2_flow_create,
3654 .validate = dpaa2_flow_validate,
3655 .destroy = dpaa2_flow_destroy,
3656 .flush = dpaa2_flow_flush,
3657 .query = dpaa2_flow_query,