15f176728SJun Yang /* SPDX-License-Identifier: BSD-3-Clause 256c1817dSJun Yang * Copyright 2018-2022 NXP 3fe2b986aSSunil Kumar Kori */ 4fe2b986aSSunil Kumar Kori 5fe2b986aSSunil Kumar Kori #include <sys/queue.h> 6fe2b986aSSunil Kumar Kori #include <stdio.h> 7fe2b986aSSunil Kumar Kori #include <errno.h> 8fe2b986aSSunil Kumar Kori #include <stdint.h> 9fe2b986aSSunil Kumar Kori #include <string.h> 10fe2b986aSSunil Kumar Kori #include <unistd.h> 11fe2b986aSSunil Kumar Kori #include <stdarg.h> 1299400780SJun Yang #include <sys/mman.h> 13fe2b986aSSunil Kumar Kori 14fe2b986aSSunil Kumar Kori #include <rte_ethdev.h> 15fe2b986aSSunil Kumar Kori #include <rte_log.h> 16fe2b986aSSunil Kumar Kori #include <rte_malloc.h> 17fe2b986aSSunil Kumar Kori #include <rte_flow_driver.h> 18fe2b986aSSunil Kumar Kori #include <rte_tailq.h> 19fe2b986aSSunil Kumar Kori 20fe2b986aSSunil Kumar Kori #include <fsl_dpni.h> 21fe2b986aSSunil Kumar Kori #include <fsl_dpkg.h> 22fe2b986aSSunil Kumar Kori 23fe2b986aSSunil Kumar Kori #include <dpaa2_ethdev.h> 24fe2b986aSSunil Kumar Kori #include <dpaa2_pmd_logs.h> 25fe2b986aSSunil Kumar Kori 26f5ed2ea0SJun Yang static char *dpaa2_flow_control_log; 27068be45fSRohit Raj static uint16_t dpaa2_flow_miss_flow_id; /* Default miss flow id is 0. */ 2899400780SJun Yang static int dpaa2_sp_loaded = -1; 29f5ed2ea0SJun Yang 3056c1817dSJun Yang enum dpaa2_flow_entry_size { 3156c1817dSJun Yang DPAA2_FLOW_ENTRY_MIN_SIZE = (DPNI_MAX_KEY_SIZE / 2), 3256c1817dSJun Yang DPAA2_FLOW_ENTRY_MAX_SIZE = DPNI_MAX_KEY_SIZE 335f176728SJun Yang }; 345f176728SJun Yang 3556c1817dSJun Yang enum dpaa2_flow_dist_type { 3656c1817dSJun Yang DPAA2_FLOW_QOS_TYPE = 1 << 0, 3756c1817dSJun Yang DPAA2_FLOW_FS_TYPE = 1 << 1 385f176728SJun Yang }; 395f176728SJun Yang 4056c1817dSJun Yang #define DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT 16 4156c1817dSJun Yang #define DPAA2_FLOW_MAX_KEY_SIZE 16 42146c745eSJun Yang #define DPAA2_PROT_FIELD_STRING_SIZE 16 4339c8044fSJun Yang #define VXLAN_HF_VNI 0x08 4439c8044fSJun Yang 4556c1817dSJun Yang struct dpaa2_dev_flow { 4656c1817dSJun Yang LIST_ENTRY(dpaa2_dev_flow) next; 475f176728SJun Yang struct dpni_rule_cfg qos_rule; 4856c1817dSJun Yang uint8_t *qos_key_addr; 4956c1817dSJun Yang uint8_t *qos_mask_addr; 5056c1817dSJun Yang uint16_t qos_rule_size; 515f176728SJun Yang struct dpni_rule_cfg fs_rule; 52d0a77dc3SJun Yang uint8_t qos_real_key_size; 53d0a77dc3SJun Yang uint8_t fs_real_key_size; 5456c1817dSJun Yang uint8_t *fs_key_addr; 5556c1817dSJun Yang uint8_t *fs_mask_addr; 5656c1817dSJun Yang uint16_t fs_rule_size; 575f176728SJun Yang uint8_t tc_id; /** Traffic Class ID. */ 585f176728SJun Yang uint8_t tc_index; /** index within this Traffic Class. */ 5956c1817dSJun Yang enum rte_flow_action_type action_type; 6056c1817dSJun Yang struct dpni_fs_action_cfg fs_action_cfg; 61fe2b986aSSunil Kumar Kori }; 62fe2b986aSSunil Kumar Kori 639ec29343SJun Yang struct rte_dpaa2_flow_item { 649ec29343SJun Yang struct rte_flow_item generic_item; 659ec29343SJun Yang int in_tunnel; 669ec29343SJun Yang }; 679ec29343SJun Yang 68fe2b986aSSunil Kumar Kori static const 691cf6d181SJun Yang enum rte_flow_item_type dpaa2_hp_supported_pattern_type[] = { 70fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_END, 71fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_ETH, 72fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_VLAN, 73fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_IPV4, 74fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_IPV6, 75fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_ICMP, 76fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_UDP, 77fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_TCP, 78fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_SCTP, 79fe2b986aSSunil Kumar Kori RTE_FLOW_ITEM_TYPE_GRE, 801cf6d181SJun Yang RTE_FLOW_ITEM_TYPE_GTP, 814cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ESP, 824cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_AH, 831cf6d181SJun Yang RTE_FLOW_ITEM_TYPE_RAW 841cf6d181SJun Yang }; 851cf6d181SJun Yang 861cf6d181SJun Yang static const 871cf6d181SJun Yang enum rte_flow_item_type dpaa2_sp_supported_pattern_type[] = { 881cf6d181SJun Yang RTE_FLOW_ITEM_TYPE_VXLAN, 891cf6d181SJun Yang RTE_FLOW_ITEM_TYPE_ECPRI 90fe2b986aSSunil Kumar Kori }; 91fe2b986aSSunil Kumar Kori 92fe2b986aSSunil Kumar Kori static const 93fe2b986aSSunil Kumar Kori enum rte_flow_action_type dpaa2_supported_action_type[] = { 94fe2b986aSSunil Kumar Kori RTE_FLOW_ACTION_TYPE_END, 95fe2b986aSSunil Kumar Kori RTE_FLOW_ACTION_TYPE_QUEUE, 96028d1dfdSJun Yang RTE_FLOW_ACTION_TYPE_PORT_ID, 97b1e15294SIvan Malov RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT, 98fe2b986aSSunil Kumar Kori RTE_FLOW_ACTION_TYPE_RSS 99fe2b986aSSunil Kumar Kori }; 100fe2b986aSSunil Kumar Kori 101926c1279SJun Yang #ifndef __cplusplus 102926c1279SJun Yang static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = { 103e0d947a1SFerruh Yigit .hdr.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 104e0d947a1SFerruh Yigit .hdr.src_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 1058275d5fcSThomas Monjalon .hdr.ether_type = RTE_BE16(0xffff), 106926c1279SJun Yang }; 107926c1279SJun Yang 108926c1279SJun Yang static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = { 1098275d5fcSThomas Monjalon .hdr.vlan_tci = RTE_BE16(0xffff), 110926c1279SJun Yang }; 111926c1279SJun Yang 112926c1279SJun Yang static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = { 113926c1279SJun Yang .hdr.src_addr = RTE_BE32(0xffffffff), 114926c1279SJun Yang .hdr.dst_addr = RTE_BE32(0xffffffff), 115926c1279SJun Yang .hdr.next_proto_id = 0xff, 116926c1279SJun Yang }; 117926c1279SJun Yang 118926c1279SJun Yang static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = { 119926c1279SJun Yang .hdr = { 12089b5642dSRobin Jarry .src_addr = RTE_IPV6_MASK_FULL, 12189b5642dSRobin Jarry .dst_addr = RTE_IPV6_MASK_FULL, 122926c1279SJun Yang .proto = 0xff 123926c1279SJun Yang }, 124926c1279SJun Yang }; 125926c1279SJun Yang 126926c1279SJun Yang static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = { 127926c1279SJun Yang .hdr.icmp_type = 0xff, 128926c1279SJun Yang .hdr.icmp_code = 0xff, 129926c1279SJun Yang }; 130926c1279SJun Yang 131926c1279SJun Yang static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = { 132926c1279SJun Yang .hdr = { 133926c1279SJun Yang .src_port = RTE_BE16(0xffff), 134926c1279SJun Yang .dst_port = RTE_BE16(0xffff), 135926c1279SJun Yang }, 136926c1279SJun Yang }; 137926c1279SJun Yang 138926c1279SJun Yang static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = { 139926c1279SJun Yang .hdr = { 140926c1279SJun Yang .src_port = RTE_BE16(0xffff), 141926c1279SJun Yang .dst_port = RTE_BE16(0xffff), 142926c1279SJun Yang }, 143926c1279SJun Yang }; 144926c1279SJun Yang 145926c1279SJun Yang static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = { 146926c1279SJun Yang .hdr = { 147926c1279SJun Yang .src_port = RTE_BE16(0xffff), 148926c1279SJun Yang .dst_port = RTE_BE16(0xffff), 149926c1279SJun Yang }, 150926c1279SJun Yang }; 151926c1279SJun Yang 1524cc5cf4aSJun Yang static const struct rte_flow_item_esp dpaa2_flow_item_esp_mask = { 1534cc5cf4aSJun Yang .hdr = { 1544cc5cf4aSJun Yang .spi = RTE_BE32(0xffffffff), 1554cc5cf4aSJun Yang .seq = RTE_BE32(0xffffffff), 1564cc5cf4aSJun Yang }, 1574cc5cf4aSJun Yang }; 1584cc5cf4aSJun Yang 1594cc5cf4aSJun Yang static const struct rte_flow_item_ah dpaa2_flow_item_ah_mask = { 1604cc5cf4aSJun Yang .spi = RTE_BE32(0xffffffff), 1614cc5cf4aSJun Yang }; 1624cc5cf4aSJun Yang 163926c1279SJun Yang static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = { 164926c1279SJun Yang .protocol = RTE_BE16(0xffff), 165926c1279SJun Yang }; 16639c8044fSJun Yang 16739c8044fSJun Yang static const struct rte_flow_item_vxlan dpaa2_flow_item_vxlan_mask = { 16839c8044fSJun Yang .flags = 0xff, 169*11f84bf4SStephen Hemminger .vni = { 0xff, 0xff, 0xff }, 17039c8044fSJun Yang }; 171a8a6b82eSJun Yang 172a8a6b82eSJun Yang static const struct rte_flow_item_ecpri dpaa2_flow_item_ecpri_mask = { 173a8a6b82eSJun Yang .hdr.common.type = 0xff, 174a8a6b82eSJun Yang .hdr.dummy[0] = RTE_BE32(0xffffffff), 175a8a6b82eSJun Yang .hdr.dummy[1] = RTE_BE32(0xffffffff), 176a8a6b82eSJun Yang .hdr.dummy[2] = RTE_BE32(0xffffffff), 177a8a6b82eSJun Yang }; 178146c745eSJun Yang 179146c745eSJun Yang static const struct rte_flow_item_gtp dpaa2_flow_item_gtp_mask = { 180146c745eSJun Yang .teid = RTE_BE32(0xffffffff), 181146c745eSJun Yang }; 182146c745eSJun Yang 183926c1279SJun Yang #endif 184926c1279SJun Yang 18556c1817dSJun Yang #define DPAA2_FLOW_DUMP printf 18656c1817dSJun Yang 18756c1817dSJun Yang static inline void 18856c1817dSJun Yang dpaa2_prot_field_string(uint32_t prot, uint32_t field, 189f5ed2ea0SJun Yang char *string) 190f5ed2ea0SJun Yang { 191f5ed2ea0SJun Yang if (!dpaa2_flow_control_log) 192f5ed2ea0SJun Yang return; 193f5ed2ea0SJun Yang 194f5ed2ea0SJun Yang if (prot == NET_PROT_ETH) { 195f5ed2ea0SJun Yang strcpy(string, "eth"); 196f5ed2ea0SJun Yang if (field == NH_FLD_ETH_DA) 197f5ed2ea0SJun Yang strcat(string, ".dst"); 198f5ed2ea0SJun Yang else if (field == NH_FLD_ETH_SA) 199f5ed2ea0SJun Yang strcat(string, ".src"); 200f5ed2ea0SJun Yang else if (field == NH_FLD_ETH_TYPE) 201f5ed2ea0SJun Yang strcat(string, ".type"); 202f5ed2ea0SJun Yang else 203f5ed2ea0SJun Yang strcat(string, ".unknown field"); 204f5ed2ea0SJun Yang } else if (prot == NET_PROT_VLAN) { 205f5ed2ea0SJun Yang strcpy(string, "vlan"); 206f5ed2ea0SJun Yang if (field == NH_FLD_VLAN_TCI) 207f5ed2ea0SJun Yang strcat(string, ".tci"); 208f5ed2ea0SJun Yang else 209f5ed2ea0SJun Yang strcat(string, ".unknown field"); 210f5ed2ea0SJun Yang } else if (prot == NET_PROT_IP) { 211f5ed2ea0SJun Yang strcpy(string, "ip"); 212f5ed2ea0SJun Yang if (field == NH_FLD_IP_SRC) 213f5ed2ea0SJun Yang strcat(string, ".src"); 214f5ed2ea0SJun Yang else if (field == NH_FLD_IP_DST) 215f5ed2ea0SJun Yang strcat(string, ".dst"); 216f5ed2ea0SJun Yang else if (field == NH_FLD_IP_PROTO) 217f5ed2ea0SJun Yang strcat(string, ".proto"); 218f5ed2ea0SJun Yang else 219f5ed2ea0SJun Yang strcat(string, ".unknown field"); 220f5ed2ea0SJun Yang } else if (prot == NET_PROT_TCP) { 221f5ed2ea0SJun Yang strcpy(string, "tcp"); 222f5ed2ea0SJun Yang if (field == NH_FLD_TCP_PORT_SRC) 223f5ed2ea0SJun Yang strcat(string, ".src"); 224f5ed2ea0SJun Yang else if (field == NH_FLD_TCP_PORT_DST) 225f5ed2ea0SJun Yang strcat(string, ".dst"); 226f5ed2ea0SJun Yang else 227f5ed2ea0SJun Yang strcat(string, ".unknown field"); 228f5ed2ea0SJun Yang } else if (prot == NET_PROT_UDP) { 229f5ed2ea0SJun Yang strcpy(string, "udp"); 230f5ed2ea0SJun Yang if (field == NH_FLD_UDP_PORT_SRC) 231f5ed2ea0SJun Yang strcat(string, ".src"); 232f5ed2ea0SJun Yang else if (field == NH_FLD_UDP_PORT_DST) 233f5ed2ea0SJun Yang strcat(string, ".dst"); 234f5ed2ea0SJun Yang else 235f5ed2ea0SJun Yang strcat(string, ".unknown field"); 236f5ed2ea0SJun Yang } else if (prot == NET_PROT_ICMP) { 237f5ed2ea0SJun Yang strcpy(string, "icmp"); 238f5ed2ea0SJun Yang if (field == NH_FLD_ICMP_TYPE) 239f5ed2ea0SJun Yang strcat(string, ".type"); 240f5ed2ea0SJun Yang else if (field == NH_FLD_ICMP_CODE) 241f5ed2ea0SJun Yang strcat(string, ".code"); 242f5ed2ea0SJun Yang else 243f5ed2ea0SJun Yang strcat(string, ".unknown field"); 244f5ed2ea0SJun Yang } else if (prot == NET_PROT_SCTP) { 245f5ed2ea0SJun Yang strcpy(string, "sctp"); 246f5ed2ea0SJun Yang if (field == NH_FLD_SCTP_PORT_SRC) 247f5ed2ea0SJun Yang strcat(string, ".src"); 248f5ed2ea0SJun Yang else if (field == NH_FLD_SCTP_PORT_DST) 249f5ed2ea0SJun Yang strcat(string, ".dst"); 250f5ed2ea0SJun Yang else 251f5ed2ea0SJun Yang strcat(string, ".unknown field"); 252f5ed2ea0SJun Yang } else if (prot == NET_PROT_GRE) { 253f5ed2ea0SJun Yang strcpy(string, "gre"); 254f5ed2ea0SJun Yang if (field == NH_FLD_GRE_TYPE) 255f5ed2ea0SJun Yang strcat(string, ".type"); 256f5ed2ea0SJun Yang else 257f5ed2ea0SJun Yang strcat(string, ".unknown field"); 258146c745eSJun Yang } else if (prot == NET_PROT_GTP) { 259146c745eSJun Yang rte_strscpy(string, "gtp", DPAA2_PROT_FIELD_STRING_SIZE); 260146c745eSJun Yang if (field == NH_FLD_GTP_TEID) 261146c745eSJun Yang strcat(string, ".teid"); 262146c745eSJun Yang else 263146c745eSJun Yang strcat(string, ".unknown field"); 2644cc5cf4aSJun Yang } else if (prot == NET_PROT_IPSEC_ESP) { 2654cc5cf4aSJun Yang rte_strscpy(string, "esp", DPAA2_PROT_FIELD_STRING_SIZE); 2664cc5cf4aSJun Yang if (field == NH_FLD_IPSEC_ESP_SPI) 2674cc5cf4aSJun Yang strcat(string, ".spi"); 2684cc5cf4aSJun Yang else if (field == NH_FLD_IPSEC_ESP_SEQUENCE_NUM) 2694cc5cf4aSJun Yang strcat(string, ".seq"); 2704cc5cf4aSJun Yang else 2714cc5cf4aSJun Yang strcat(string, ".unknown field"); 272f5ed2ea0SJun Yang } else { 2734cc5cf4aSJun Yang sprintf(string, "unknown protocol(%d)", prot); 274f5ed2ea0SJun Yang } 275f5ed2ea0SJun Yang } 276f5ed2ea0SJun Yang 27756c1817dSJun Yang static inline void 27856c1817dSJun Yang dpaa2_flow_qos_extracts_log(const struct dpaa2_dev_priv *priv) 279f5ed2ea0SJun Yang { 280f5ed2ea0SJun Yang int idx; 281f5ed2ea0SJun Yang char string[32]; 28256c1817dSJun Yang const struct dpkg_profile_cfg *dpkg = 28356c1817dSJun Yang &priv->extract.qos_key_extract.dpkg; 28456c1817dSJun Yang const struct dpkg_extract *extract; 28556c1817dSJun Yang enum dpkg_extract_type type; 28656c1817dSJun Yang enum net_prot prot; 28756c1817dSJun Yang uint32_t field; 288f5ed2ea0SJun Yang 289f5ed2ea0SJun Yang if (!dpaa2_flow_control_log) 290f5ed2ea0SJun Yang return; 291f5ed2ea0SJun Yang 29256c1817dSJun Yang DPAA2_FLOW_DUMP("QoS table: %d extracts\r\n", 29356c1817dSJun Yang dpkg->num_extracts); 29456c1817dSJun Yang for (idx = 0; idx < dpkg->num_extracts; idx++) { 29556c1817dSJun Yang extract = &dpkg->extracts[idx]; 29656c1817dSJun Yang type = extract->type; 29756c1817dSJun Yang if (type == DPKG_EXTRACT_FROM_HDR) { 29856c1817dSJun Yang prot = extract->extract.from_hdr.prot; 29956c1817dSJun Yang field = extract->extract.from_hdr.field; 30056c1817dSJun Yang dpaa2_prot_field_string(prot, field, 301f5ed2ea0SJun Yang string); 30256c1817dSJun Yang } else if (type == DPKG_EXTRACT_FROM_DATA) { 30356c1817dSJun Yang sprintf(string, "raw offset/len: %d/%d", 30456c1817dSJun Yang extract->extract.from_data.offset, 30556c1817dSJun Yang extract->extract.from_data.size); 306200a33e4SJun Yang } else if (type == DPKG_EXTRACT_FROM_PARSE) { 307200a33e4SJun Yang sprintf(string, "parse offset/len: %d/%d", 308200a33e4SJun Yang extract->extract.from_parse.offset, 309200a33e4SJun Yang extract->extract.from_parse.size); 310f5ed2ea0SJun Yang } 31156c1817dSJun Yang DPAA2_FLOW_DUMP("%s", string); 31256c1817dSJun Yang if ((idx + 1) < dpkg->num_extracts) 31356c1817dSJun Yang DPAA2_FLOW_DUMP(" / "); 31456c1817dSJun Yang } 31556c1817dSJun Yang DPAA2_FLOW_DUMP("\r\n"); 316f5ed2ea0SJun Yang } 317f5ed2ea0SJun Yang 31856c1817dSJun Yang static inline void 31956c1817dSJun Yang dpaa2_flow_fs_extracts_log(const struct dpaa2_dev_priv *priv, 32056c1817dSJun Yang int tc_id) 321f5ed2ea0SJun Yang { 322f5ed2ea0SJun Yang int idx; 323f5ed2ea0SJun Yang char string[32]; 32456c1817dSJun Yang const struct dpkg_profile_cfg *dpkg = 32556c1817dSJun Yang &priv->extract.tc_key_extract[tc_id].dpkg; 32656c1817dSJun Yang const struct dpkg_extract *extract; 32756c1817dSJun Yang enum dpkg_extract_type type; 32856c1817dSJun Yang enum net_prot prot; 32956c1817dSJun Yang uint32_t field; 330f5ed2ea0SJun Yang 331f5ed2ea0SJun Yang if (!dpaa2_flow_control_log) 332f5ed2ea0SJun Yang return; 333f5ed2ea0SJun Yang 33456c1817dSJun Yang DPAA2_FLOW_DUMP("FS table: %d extracts in TC[%d]\r\n", 33556c1817dSJun Yang dpkg->num_extracts, tc_id); 33656c1817dSJun Yang for (idx = 0; idx < dpkg->num_extracts; idx++) { 33756c1817dSJun Yang extract = &dpkg->extracts[idx]; 33856c1817dSJun Yang type = extract->type; 33956c1817dSJun Yang if (type == DPKG_EXTRACT_FROM_HDR) { 34056c1817dSJun Yang prot = extract->extract.from_hdr.prot; 34156c1817dSJun Yang field = extract->extract.from_hdr.field; 34256c1817dSJun Yang dpaa2_prot_field_string(prot, field, 343f5ed2ea0SJun Yang string); 34456c1817dSJun Yang } else if (type == DPKG_EXTRACT_FROM_DATA) { 34556c1817dSJun Yang sprintf(string, "raw offset/len: %d/%d", 34656c1817dSJun Yang extract->extract.from_data.offset, 34756c1817dSJun Yang extract->extract.from_data.size); 348200a33e4SJun Yang } else if (type == DPKG_EXTRACT_FROM_PARSE) { 349200a33e4SJun Yang sprintf(string, "parse offset/len: %d/%d", 350200a33e4SJun Yang extract->extract.from_parse.offset, 351200a33e4SJun Yang extract->extract.from_parse.size); 352f5ed2ea0SJun Yang } 35356c1817dSJun Yang DPAA2_FLOW_DUMP("%s", string); 35456c1817dSJun Yang if ((idx + 1) < dpkg->num_extracts) 35556c1817dSJun Yang DPAA2_FLOW_DUMP(" / "); 35656c1817dSJun Yang } 35756c1817dSJun Yang DPAA2_FLOW_DUMP("\r\n"); 358f5ed2ea0SJun Yang } 359f5ed2ea0SJun Yang 36056c1817dSJun Yang static inline void 36156c1817dSJun Yang dpaa2_flow_qos_entry_log(const char *log_info, 36256c1817dSJun Yang const struct dpaa2_dev_flow *flow, int qos_index) 363f5ed2ea0SJun Yang { 364f5ed2ea0SJun Yang int idx; 365f5ed2ea0SJun Yang uint8_t *key, *mask; 366f5ed2ea0SJun Yang 367f5ed2ea0SJun Yang if (!dpaa2_flow_control_log) 368f5ed2ea0SJun Yang return; 369f5ed2ea0SJun Yang 37056c1817dSJun Yang if (qos_index >= 0) { 37156c1817dSJun Yang DPAA2_FLOW_DUMP("%s QoS entry[%d](size %d/%d) for TC[%d]\r\n", 37256c1817dSJun Yang log_info, qos_index, flow->qos_rule_size, 37356c1817dSJun Yang flow->qos_rule.key_size, 37456c1817dSJun Yang flow->tc_id); 3755f176728SJun Yang } else { 37656c1817dSJun Yang DPAA2_FLOW_DUMP("%s QoS entry(size %d/%d) for TC[%d]\r\n", 37756c1817dSJun Yang log_info, flow->qos_rule_size, 37856c1817dSJun Yang flow->qos_rule.key_size, 37956c1817dSJun Yang flow->tc_id); 3805f176728SJun Yang } 3815f176728SJun Yang 38256c1817dSJun Yang key = flow->qos_key_addr; 38356c1817dSJun Yang mask = flow->qos_mask_addr; 38456c1817dSJun Yang 38556c1817dSJun Yang DPAA2_FLOW_DUMP("key:\r\n"); 38656c1817dSJun Yang for (idx = 0; idx < flow->qos_rule_size; idx++) 38756c1817dSJun Yang DPAA2_FLOW_DUMP("%02x ", key[idx]); 38856c1817dSJun Yang 38956c1817dSJun Yang DPAA2_FLOW_DUMP("\r\nmask:\r\n"); 39056c1817dSJun Yang for (idx = 0; idx < flow->qos_rule_size; idx++) 39156c1817dSJun Yang DPAA2_FLOW_DUMP("%02x ", mask[idx]); 39256c1817dSJun Yang DPAA2_FLOW_DUMP("\r\n"); 39356c1817dSJun Yang } 39456c1817dSJun Yang 39556c1817dSJun Yang static inline void 39656c1817dSJun Yang dpaa2_flow_fs_entry_log(const char *log_info, 39756c1817dSJun Yang const struct dpaa2_dev_flow *flow) 3985f176728SJun Yang { 39956c1817dSJun Yang int idx; 40056c1817dSJun Yang uint8_t *key, *mask; 4015f176728SJun Yang 40256c1817dSJun Yang if (!dpaa2_flow_control_log) 40356c1817dSJun Yang return; 40456c1817dSJun Yang 40556c1817dSJun Yang DPAA2_FLOW_DUMP("%s FS/TC entry[%d](size %d/%d) of TC[%d]\r\n", 40656c1817dSJun Yang log_info, flow->tc_index, 40756c1817dSJun Yang flow->fs_rule_size, flow->fs_rule.key_size, 40856c1817dSJun Yang flow->tc_id); 40956c1817dSJun Yang 41056c1817dSJun Yang key = flow->fs_key_addr; 41156c1817dSJun Yang mask = flow->fs_mask_addr; 41256c1817dSJun Yang 41356c1817dSJun Yang DPAA2_FLOW_DUMP("key:\r\n"); 41456c1817dSJun Yang for (idx = 0; idx < flow->fs_rule_size; idx++) 41556c1817dSJun Yang DPAA2_FLOW_DUMP("%02x ", key[idx]); 41656c1817dSJun Yang 41756c1817dSJun Yang DPAA2_FLOW_DUMP("\r\nmask:\r\n"); 41856c1817dSJun Yang for (idx = 0; idx < flow->fs_rule_size; idx++) 41956c1817dSJun Yang DPAA2_FLOW_DUMP("%02x ", mask[idx]); 42056c1817dSJun Yang DPAA2_FLOW_DUMP("\r\n"); 4215f176728SJun Yang } 42256c1817dSJun Yang 42399400780SJun Yang /** For LX2160A, LS2088A and LS1088A*/ 42499400780SJun Yang #define WRIOP_CCSR_BASE 0x8b80000 42599400780SJun Yang #define WRIOP_CCSR_CTLU_OFFSET 0 42699400780SJun Yang #define WRIOP_CCSR_CTLU_PARSER_OFFSET 0 42799400780SJun Yang #define WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET 0 42899400780SJun Yang 42999400780SJun Yang #define WRIOP_INGRESS_PARSER_PHY \ 43099400780SJun Yang (WRIOP_CCSR_BASE + WRIOP_CCSR_CTLU_OFFSET + \ 43199400780SJun Yang WRIOP_CCSR_CTLU_PARSER_OFFSET + \ 43299400780SJun Yang WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET) 43399400780SJun Yang 43499400780SJun Yang struct dpaa2_parser_ccsr { 43599400780SJun Yang uint32_t psr_cfg; 43699400780SJun Yang uint32_t psr_idle; 43799400780SJun Yang uint32_t psr_pclm; 43899400780SJun Yang uint8_t psr_ver_min; 43999400780SJun Yang uint8_t psr_ver_maj; 44099400780SJun Yang uint8_t psr_id1_l; 44199400780SJun Yang uint8_t psr_id1_h; 44299400780SJun Yang uint32_t psr_rev2; 44399400780SJun Yang uint8_t rsv[0x2c]; 44499400780SJun Yang uint8_t sp_ins[4032]; 44599400780SJun Yang }; 44699400780SJun Yang 44799400780SJun Yang int 44899400780SJun Yang dpaa2_soft_parser_loaded(void) 44999400780SJun Yang { 45099400780SJun Yang int fd, i, ret = 0; 45199400780SJun Yang struct dpaa2_parser_ccsr *parser_ccsr = NULL; 45299400780SJun Yang 45399400780SJun Yang dpaa2_flow_control_log = getenv("DPAA2_FLOW_CONTROL_LOG"); 45499400780SJun Yang 45599400780SJun Yang if (dpaa2_sp_loaded >= 0) 45699400780SJun Yang return dpaa2_sp_loaded; 45799400780SJun Yang 45899400780SJun Yang fd = open("/dev/mem", O_RDWR | O_SYNC); 45999400780SJun Yang if (fd < 0) { 46099400780SJun Yang DPAA2_PMD_ERR("open \"/dev/mem\" ERROR(%d)", fd); 46199400780SJun Yang ret = fd; 46299400780SJun Yang goto exit; 46399400780SJun Yang } 46499400780SJun Yang 46599400780SJun Yang parser_ccsr = mmap(NULL, sizeof(struct dpaa2_parser_ccsr), 46699400780SJun Yang PROT_READ | PROT_WRITE, MAP_SHARED, fd, 46799400780SJun Yang WRIOP_INGRESS_PARSER_PHY); 46899400780SJun Yang if (!parser_ccsr) { 46999400780SJun Yang DPAA2_PMD_ERR("Map 0x%" PRIx64 "(size=0x%x) failed", 47099400780SJun Yang (uint64_t)WRIOP_INGRESS_PARSER_PHY, 47199400780SJun Yang (uint32_t)sizeof(struct dpaa2_parser_ccsr)); 47299400780SJun Yang ret = -ENOBUFS; 47399400780SJun Yang goto exit; 47499400780SJun Yang } 47599400780SJun Yang 47699400780SJun Yang DPAA2_PMD_INFO("Parser ID:0x%02x%02x, Rev:major(%02x), minor(%02x)", 47799400780SJun Yang parser_ccsr->psr_id1_h, parser_ccsr->psr_id1_l, 47899400780SJun Yang parser_ccsr->psr_ver_maj, parser_ccsr->psr_ver_min); 47999400780SJun Yang 48099400780SJun Yang if (dpaa2_flow_control_log) { 48199400780SJun Yang for (i = 0; i < 64; i++) { 48299400780SJun Yang DPAA2_FLOW_DUMP("%02x ", 48399400780SJun Yang parser_ccsr->sp_ins[i]); 48499400780SJun Yang if (!((i + 1) % 16)) 48599400780SJun Yang DPAA2_FLOW_DUMP("\r\n"); 48699400780SJun Yang } 48799400780SJun Yang } 48899400780SJun Yang 48999400780SJun Yang for (i = 0; i < 16; i++) { 49099400780SJun Yang if (parser_ccsr->sp_ins[i]) { 49199400780SJun Yang dpaa2_sp_loaded = 1; 49299400780SJun Yang break; 49399400780SJun Yang } 49499400780SJun Yang } 49599400780SJun Yang if (dpaa2_sp_loaded < 0) 49699400780SJun Yang dpaa2_sp_loaded = 0; 49799400780SJun Yang 49899400780SJun Yang ret = dpaa2_sp_loaded; 49999400780SJun Yang 50099400780SJun Yang exit: 50199400780SJun Yang if (parser_ccsr) 50299400780SJun Yang munmap(parser_ccsr, sizeof(struct dpaa2_parser_ccsr)); 50399400780SJun Yang if (fd >= 0) 50499400780SJun Yang close(fd); 50599400780SJun Yang 50699400780SJun Yang return ret; 50799400780SJun Yang } 50899400780SJun Yang 50956c1817dSJun Yang static int 51056c1817dSJun Yang dpaa2_flow_ip_address_extract(enum net_prot prot, 51156c1817dSJun Yang uint32_t field) 51256c1817dSJun Yang { 51356c1817dSJun Yang if (prot == NET_PROT_IPV4 && 51456c1817dSJun Yang (field == NH_FLD_IPV4_SRC_IP || 51556c1817dSJun Yang field == NH_FLD_IPV4_DST_IP)) 51656c1817dSJun Yang return true; 51756c1817dSJun Yang else if (prot == NET_PROT_IPV6 && 51856c1817dSJun Yang (field == NH_FLD_IPV6_SRC_IP || 51956c1817dSJun Yang field == NH_FLD_IPV6_DST_IP)) 52056c1817dSJun Yang return true; 52156c1817dSJun Yang else if (prot == NET_PROT_IP && 52256c1817dSJun Yang (field == NH_FLD_IP_SRC || 52356c1817dSJun Yang field == NH_FLD_IP_DST)) 52456c1817dSJun Yang return true; 52556c1817dSJun Yang 52656c1817dSJun Yang return false; 52756c1817dSJun Yang } 52856c1817dSJun Yang 52956c1817dSJun Yang static int 53056c1817dSJun Yang dpaa2_flow_l4_src_port_extract(enum net_prot prot, 53156c1817dSJun Yang uint32_t field) 53256c1817dSJun Yang { 53356c1817dSJun Yang if (prot == NET_PROT_TCP && 53456c1817dSJun Yang field == NH_FLD_TCP_PORT_SRC) 53556c1817dSJun Yang return true; 53656c1817dSJun Yang else if (prot == NET_PROT_UDP && 53756c1817dSJun Yang field == NH_FLD_UDP_PORT_SRC) 53856c1817dSJun Yang return true; 53956c1817dSJun Yang else if (prot == NET_PROT_SCTP && 54056c1817dSJun Yang field == NH_FLD_SCTP_PORT_SRC) 54156c1817dSJun Yang return true; 54256c1817dSJun Yang 54356c1817dSJun Yang return false; 54456c1817dSJun Yang } 54556c1817dSJun Yang 54656c1817dSJun Yang static int 54756c1817dSJun Yang dpaa2_flow_l4_dst_port_extract(enum net_prot prot, 54856c1817dSJun Yang uint32_t field) 54956c1817dSJun Yang { 55056c1817dSJun Yang if (prot == NET_PROT_TCP && 55156c1817dSJun Yang field == NH_FLD_TCP_PORT_DST) 55256c1817dSJun Yang return true; 55356c1817dSJun Yang else if (prot == NET_PROT_UDP && 55456c1817dSJun Yang field == NH_FLD_UDP_PORT_DST) 55556c1817dSJun Yang return true; 55656c1817dSJun Yang else if (prot == NET_PROT_SCTP && 55756c1817dSJun Yang field == NH_FLD_SCTP_PORT_DST) 55856c1817dSJun Yang return true; 55956c1817dSJun Yang 56056c1817dSJun Yang return false; 56156c1817dSJun Yang } 56256c1817dSJun Yang 56356c1817dSJun Yang static int 56456c1817dSJun Yang dpaa2_flow_add_qos_rule(struct dpaa2_dev_priv *priv, 56556c1817dSJun Yang struct dpaa2_dev_flow *flow) 56656c1817dSJun Yang { 56756c1817dSJun Yang uint16_t qos_index; 56856c1817dSJun Yang int ret; 56956c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 57056c1817dSJun Yang 57156c1817dSJun Yang if (priv->num_rx_tc <= 1 && 57256c1817dSJun Yang flow->action_type != RTE_FLOW_ACTION_TYPE_RSS) { 57356c1817dSJun Yang DPAA2_PMD_WARN("No QoS Table for FS"); 57456c1817dSJun Yang return -EINVAL; 57556c1817dSJun Yang } 57656c1817dSJun Yang 57756c1817dSJun Yang /* QoS entry added is only effective for multiple TCs.*/ 57856c1817dSJun Yang qos_index = flow->tc_id * priv->fs_entries + flow->tc_index; 57956c1817dSJun Yang if (qos_index >= priv->qos_entries) { 58056c1817dSJun Yang DPAA2_PMD_ERR("QoS table full(%d >= %d)", 58156c1817dSJun Yang qos_index, priv->qos_entries); 58256c1817dSJun Yang return -EINVAL; 58356c1817dSJun Yang } 58456c1817dSJun Yang 58556c1817dSJun Yang dpaa2_flow_qos_entry_log("Start add", flow, qos_index); 58656c1817dSJun Yang 58756c1817dSJun Yang ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, 58856c1817dSJun Yang priv->token, &flow->qos_rule, 58956c1817dSJun Yang flow->tc_id, qos_index, 59056c1817dSJun Yang 0, 0); 59156c1817dSJun Yang if (ret < 0) { 59256c1817dSJun Yang DPAA2_PMD_ERR("Add entry(%d) to table(%d) failed", 59356c1817dSJun Yang qos_index, flow->tc_id); 59456c1817dSJun Yang return ret; 59556c1817dSJun Yang } 59656c1817dSJun Yang 59756c1817dSJun Yang return 0; 59856c1817dSJun Yang } 59956c1817dSJun Yang 60056c1817dSJun Yang static int 60156c1817dSJun Yang dpaa2_flow_add_fs_rule(struct dpaa2_dev_priv *priv, 60256c1817dSJun Yang struct dpaa2_dev_flow *flow) 60356c1817dSJun Yang { 60456c1817dSJun Yang int ret; 60556c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 60656c1817dSJun Yang 60756c1817dSJun Yang if (flow->tc_index >= priv->fs_entries) { 60856c1817dSJun Yang DPAA2_PMD_ERR("FS table full(%d >= %d)", 60956c1817dSJun Yang flow->tc_index, priv->fs_entries); 61056c1817dSJun Yang return -EINVAL; 61156c1817dSJun Yang } 61256c1817dSJun Yang 61356c1817dSJun Yang dpaa2_flow_fs_entry_log("Start add", flow); 61456c1817dSJun Yang 61556c1817dSJun Yang ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, 61656c1817dSJun Yang priv->token, flow->tc_id, 61756c1817dSJun Yang flow->tc_index, &flow->fs_rule, 61856c1817dSJun Yang &flow->fs_action_cfg); 61956c1817dSJun Yang if (ret < 0) { 62056c1817dSJun Yang DPAA2_PMD_ERR("Add rule(%d) to FS table(%d) failed", 62156c1817dSJun Yang flow->tc_index, flow->tc_id); 62256c1817dSJun Yang return ret; 62356c1817dSJun Yang } 62456c1817dSJun Yang 62556c1817dSJun Yang return 0; 62656c1817dSJun Yang } 62756c1817dSJun Yang 62856c1817dSJun Yang static int 62956c1817dSJun Yang dpaa2_flow_rule_insert_hole(struct dpaa2_dev_flow *flow, 63056c1817dSJun Yang int offset, int size, 63156c1817dSJun Yang enum dpaa2_flow_dist_type dist_type) 63256c1817dSJun Yang { 63356c1817dSJun Yang int end; 63456c1817dSJun Yang 63556c1817dSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 63656c1817dSJun Yang end = flow->qos_rule_size; 63756c1817dSJun Yang if (end > offset) { 63856c1817dSJun Yang memmove(flow->qos_key_addr + offset + size, 63956c1817dSJun Yang flow->qos_key_addr + offset, 64056c1817dSJun Yang end - offset); 64156c1817dSJun Yang memset(flow->qos_key_addr + offset, 64256c1817dSJun Yang 0, size); 64356c1817dSJun Yang 64456c1817dSJun Yang memmove(flow->qos_mask_addr + offset + size, 64556c1817dSJun Yang flow->qos_mask_addr + offset, 64656c1817dSJun Yang end - offset); 64756c1817dSJun Yang memset(flow->qos_mask_addr + offset, 64856c1817dSJun Yang 0, size); 64956c1817dSJun Yang } 65056c1817dSJun Yang flow->qos_rule_size += size; 65156c1817dSJun Yang } 65256c1817dSJun Yang 65356c1817dSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 65456c1817dSJun Yang end = flow->fs_rule_size; 65556c1817dSJun Yang if (end > offset) { 65656c1817dSJun Yang memmove(flow->fs_key_addr + offset + size, 65756c1817dSJun Yang flow->fs_key_addr + offset, 65856c1817dSJun Yang end - offset); 65956c1817dSJun Yang memset(flow->fs_key_addr + offset, 66056c1817dSJun Yang 0, size); 66156c1817dSJun Yang 66256c1817dSJun Yang memmove(flow->fs_mask_addr + offset + size, 66356c1817dSJun Yang flow->fs_mask_addr + offset, 66456c1817dSJun Yang end - offset); 66556c1817dSJun Yang memset(flow->fs_mask_addr + offset, 66656c1817dSJun Yang 0, size); 66756c1817dSJun Yang } 66856c1817dSJun Yang flow->fs_rule_size += size; 66956c1817dSJun Yang } 67056c1817dSJun Yang 67156c1817dSJun Yang return 0; 67256c1817dSJun Yang } 67356c1817dSJun Yang 67456c1817dSJun Yang static int 67556c1817dSJun Yang dpaa2_flow_rule_add_all(struct dpaa2_dev_priv *priv, 67656c1817dSJun Yang enum dpaa2_flow_dist_type dist_type, 67756c1817dSJun Yang uint16_t entry_size, uint8_t tc_id) 67856c1817dSJun Yang { 67956c1817dSJun Yang struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows); 68056c1817dSJun Yang int ret; 68156c1817dSJun Yang 68256c1817dSJun Yang while (curr) { 68356c1817dSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 68456c1817dSJun Yang if (priv->num_rx_tc > 1 || 68556c1817dSJun Yang curr->action_type == 68656c1817dSJun Yang RTE_FLOW_ACTION_TYPE_RSS) { 68756c1817dSJun Yang curr->qos_rule.key_size = entry_size; 68856c1817dSJun Yang ret = dpaa2_flow_add_qos_rule(priv, curr); 68956c1817dSJun Yang if (ret) 69056c1817dSJun Yang return ret; 69156c1817dSJun Yang } 69256c1817dSJun Yang } 69356c1817dSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE && 69456c1817dSJun Yang curr->tc_id == tc_id) { 69556c1817dSJun Yang curr->fs_rule.key_size = entry_size; 69656c1817dSJun Yang ret = dpaa2_flow_add_fs_rule(priv, curr); 69756c1817dSJun Yang if (ret) 69856c1817dSJun Yang return ret; 69956c1817dSJun Yang } 70056c1817dSJun Yang curr = LIST_NEXT(curr, next); 70156c1817dSJun Yang } 70256c1817dSJun Yang 70356c1817dSJun Yang return 0; 70456c1817dSJun Yang } 70556c1817dSJun Yang 70656c1817dSJun Yang static int 70756c1817dSJun Yang dpaa2_flow_qos_rule_insert_hole(struct dpaa2_dev_priv *priv, 70856c1817dSJun Yang int offset, int size) 70956c1817dSJun Yang { 71056c1817dSJun Yang struct dpaa2_dev_flow *curr; 71156c1817dSJun Yang int ret; 71256c1817dSJun Yang 71356c1817dSJun Yang curr = priv->curr; 71456c1817dSJun Yang if (!curr) { 71556c1817dSJun Yang DPAA2_PMD_ERR("Current qos flow insert hole failed."); 71656c1817dSJun Yang return -EINVAL; 71756c1817dSJun Yang } else { 71856c1817dSJun Yang ret = dpaa2_flow_rule_insert_hole(curr, offset, size, 71956c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 72056c1817dSJun Yang if (ret) 72156c1817dSJun Yang return ret; 72256c1817dSJun Yang } 72356c1817dSJun Yang 72456c1817dSJun Yang curr = LIST_FIRST(&priv->flows); 72556c1817dSJun Yang while (curr) { 72656c1817dSJun Yang ret = dpaa2_flow_rule_insert_hole(curr, offset, size, 72756c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 72856c1817dSJun Yang if (ret) 72956c1817dSJun Yang return ret; 73056c1817dSJun Yang curr = LIST_NEXT(curr, next); 73156c1817dSJun Yang } 73256c1817dSJun Yang 73356c1817dSJun Yang return 0; 73456c1817dSJun Yang } 73556c1817dSJun Yang 73656c1817dSJun Yang static int 73756c1817dSJun Yang dpaa2_flow_fs_rule_insert_hole(struct dpaa2_dev_priv *priv, 73856c1817dSJun Yang int offset, int size, int tc_id) 73956c1817dSJun Yang { 74056c1817dSJun Yang struct dpaa2_dev_flow *curr; 74156c1817dSJun Yang int ret; 74256c1817dSJun Yang 74356c1817dSJun Yang curr = priv->curr; 74456c1817dSJun Yang if (!curr || curr->tc_id != tc_id) { 74556c1817dSJun Yang DPAA2_PMD_ERR("Current flow insert hole failed."); 74656c1817dSJun Yang return -EINVAL; 74756c1817dSJun Yang } else { 74856c1817dSJun Yang ret = dpaa2_flow_rule_insert_hole(curr, offset, size, 74956c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 75056c1817dSJun Yang if (ret) 75156c1817dSJun Yang return ret; 75256c1817dSJun Yang } 75356c1817dSJun Yang 75456c1817dSJun Yang curr = LIST_FIRST(&priv->flows); 75556c1817dSJun Yang 75656c1817dSJun Yang while (curr) { 75756c1817dSJun Yang if (curr->tc_id != tc_id) { 75856c1817dSJun Yang curr = LIST_NEXT(curr, next); 75956c1817dSJun Yang continue; 76056c1817dSJun Yang } 76156c1817dSJun Yang ret = dpaa2_flow_rule_insert_hole(curr, offset, size, 76256c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 76356c1817dSJun Yang if (ret) 76456c1817dSJun Yang return ret; 76556c1817dSJun Yang curr = LIST_NEXT(curr, next); 76656c1817dSJun Yang } 76756c1817dSJun Yang 76856c1817dSJun Yang return 0; 76956c1817dSJun Yang } 77056c1817dSJun Yang 771200a33e4SJun Yang static int 772200a33e4SJun Yang dpaa2_flow_faf_advance(struct dpaa2_dev_priv *priv, 773200a33e4SJun Yang int faf_byte, enum dpaa2_flow_dist_type dist_type, int tc_id, 774200a33e4SJun Yang int *insert_offset) 775200a33e4SJun Yang { 776200a33e4SJun Yang int offset, ret; 777200a33e4SJun Yang struct dpaa2_key_profile *key_profile; 778200a33e4SJun Yang int num, pos; 779200a33e4SJun Yang 780200a33e4SJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 781200a33e4SJun Yang key_profile = &priv->extract.qos_key_extract.key_profile; 782200a33e4SJun Yang else 783200a33e4SJun Yang key_profile = &priv->extract.tc_key_extract[tc_id].key_profile; 784200a33e4SJun Yang 785200a33e4SJun Yang num = key_profile->num; 786200a33e4SJun Yang 787200a33e4SJun Yang if (num >= DPKG_MAX_NUM_OF_EXTRACTS) { 788200a33e4SJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 789200a33e4SJun Yang return -EINVAL; 790200a33e4SJun Yang } 791200a33e4SJun Yang 792200a33e4SJun Yang if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) { 793200a33e4SJun Yang offset = key_profile->ip_addr_extract_off; 794200a33e4SJun Yang pos = key_profile->ip_addr_extract_pos; 795200a33e4SJun Yang key_profile->ip_addr_extract_pos++; 796200a33e4SJun Yang key_profile->ip_addr_extract_off++; 797200a33e4SJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 798200a33e4SJun Yang ret = dpaa2_flow_qos_rule_insert_hole(priv, 799200a33e4SJun Yang offset, 1); 800200a33e4SJun Yang } else { 801200a33e4SJun Yang ret = dpaa2_flow_fs_rule_insert_hole(priv, 802200a33e4SJun Yang offset, 1, tc_id); 803200a33e4SJun Yang } 804200a33e4SJun Yang if (ret) 805200a33e4SJun Yang return ret; 806200a33e4SJun Yang } else { 807200a33e4SJun Yang pos = num; 808200a33e4SJun Yang } 809200a33e4SJun Yang 810200a33e4SJun Yang if (pos > 0) { 811200a33e4SJun Yang key_profile->key_offset[pos] = 812200a33e4SJun Yang key_profile->key_offset[pos - 1] + 813200a33e4SJun Yang key_profile->key_size[pos - 1]; 814200a33e4SJun Yang } else { 815200a33e4SJun Yang key_profile->key_offset[pos] = 0; 816200a33e4SJun Yang } 817200a33e4SJun Yang 818200a33e4SJun Yang key_profile->key_size[pos] = 1; 819200a33e4SJun Yang key_profile->prot_field[pos].type = DPAA2_FAF_KEY; 820200a33e4SJun Yang key_profile->prot_field[pos].key_field = faf_byte; 821200a33e4SJun Yang key_profile->num++; 822200a33e4SJun Yang 823200a33e4SJun Yang if (insert_offset) 824200a33e4SJun Yang *insert_offset = key_profile->key_offset[pos]; 825200a33e4SJun Yang 826200a33e4SJun Yang key_profile->key_max_size++; 827200a33e4SJun Yang 828200a33e4SJun Yang return pos; 829200a33e4SJun Yang } 830200a33e4SJun Yang 83139c8044fSJun Yang static int 83239c8044fSJun Yang dpaa2_flow_pr_advance(struct dpaa2_dev_priv *priv, 83339c8044fSJun Yang uint32_t pr_offset, uint32_t pr_size, 83439c8044fSJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id, 83539c8044fSJun Yang int *insert_offset) 83639c8044fSJun Yang { 83739c8044fSJun Yang int offset, ret; 83839c8044fSJun Yang struct dpaa2_key_profile *key_profile; 83939c8044fSJun Yang int num, pos; 84039c8044fSJun Yang 84139c8044fSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 84239c8044fSJun Yang key_profile = &priv->extract.qos_key_extract.key_profile; 84339c8044fSJun Yang else 84439c8044fSJun Yang key_profile = &priv->extract.tc_key_extract[tc_id].key_profile; 84539c8044fSJun Yang 84639c8044fSJun Yang num = key_profile->num; 84739c8044fSJun Yang 84839c8044fSJun Yang if (num >= DPKG_MAX_NUM_OF_EXTRACTS) { 84939c8044fSJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 85039c8044fSJun Yang return -EINVAL; 85139c8044fSJun Yang } 85239c8044fSJun Yang 85339c8044fSJun Yang if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) { 85439c8044fSJun Yang offset = key_profile->ip_addr_extract_off; 85539c8044fSJun Yang pos = key_profile->ip_addr_extract_pos; 85639c8044fSJun Yang key_profile->ip_addr_extract_pos++; 85739c8044fSJun Yang key_profile->ip_addr_extract_off += pr_size; 85839c8044fSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 85939c8044fSJun Yang ret = dpaa2_flow_qos_rule_insert_hole(priv, 86039c8044fSJun Yang offset, pr_size); 86139c8044fSJun Yang } else { 86239c8044fSJun Yang ret = dpaa2_flow_fs_rule_insert_hole(priv, 86339c8044fSJun Yang offset, pr_size, tc_id); 86439c8044fSJun Yang } 86539c8044fSJun Yang if (ret) 86639c8044fSJun Yang return ret; 86739c8044fSJun Yang } else { 86839c8044fSJun Yang pos = num; 86939c8044fSJun Yang } 87039c8044fSJun Yang 87139c8044fSJun Yang if (pos > 0) { 87239c8044fSJun Yang key_profile->key_offset[pos] = 87339c8044fSJun Yang key_profile->key_offset[pos - 1] + 87439c8044fSJun Yang key_profile->key_size[pos - 1]; 87539c8044fSJun Yang } else { 87639c8044fSJun Yang key_profile->key_offset[pos] = 0; 87739c8044fSJun Yang } 87839c8044fSJun Yang 87939c8044fSJun Yang key_profile->key_size[pos] = pr_size; 88039c8044fSJun Yang key_profile->prot_field[pos].type = DPAA2_PR_KEY; 88139c8044fSJun Yang key_profile->prot_field[pos].key_field = 88239c8044fSJun Yang (pr_offset << 16) | pr_size; 88339c8044fSJun Yang key_profile->num++; 88439c8044fSJun Yang 88539c8044fSJun Yang if (insert_offset) 88639c8044fSJun Yang *insert_offset = key_profile->key_offset[pos]; 88739c8044fSJun Yang 88839c8044fSJun Yang key_profile->key_max_size += pr_size; 88939c8044fSJun Yang 89039c8044fSJun Yang return pos; 89139c8044fSJun Yang } 89239c8044fSJun Yang 89356c1817dSJun Yang /* Move IPv4/IPv6 addresses to fill new extract previous IP address. 89456c1817dSJun Yang * Current MC/WRIOP only support generic IP extract but IP address 89556c1817dSJun Yang * is not fixed, so we have to put them at end of extracts, otherwise, 89656c1817dSJun Yang * the extracts position following them can't be identified. 8975f176728SJun Yang */ 89856c1817dSJun Yang static int 89956c1817dSJun Yang dpaa2_flow_key_profile_advance(enum net_prot prot, 90056c1817dSJun Yang uint32_t field, uint8_t field_size, 90156c1817dSJun Yang struct dpaa2_dev_priv *priv, 90256c1817dSJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id, 90356c1817dSJun Yang int *insert_offset) 90456c1817dSJun Yang { 90556c1817dSJun Yang int offset, ret; 90656c1817dSJun Yang struct dpaa2_key_profile *key_profile; 90756c1817dSJun Yang int num, pos; 90856c1817dSJun Yang 90956c1817dSJun Yang if (dpaa2_flow_ip_address_extract(prot, field)) { 91056c1817dSJun Yang DPAA2_PMD_ERR("%s only for none IP address extract", 91156c1817dSJun Yang __func__); 91256c1817dSJun Yang return -EINVAL; 9135f176728SJun Yang } 9145f176728SJun Yang 91556c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 91656c1817dSJun Yang key_profile = &priv->extract.qos_key_extract.key_profile; 9175f176728SJun Yang else 91856c1817dSJun Yang key_profile = &priv->extract.tc_key_extract[tc_id].key_profile; 91956c1817dSJun Yang 92056c1817dSJun Yang num = key_profile->num; 92156c1817dSJun Yang 92256c1817dSJun Yang if (num >= DPKG_MAX_NUM_OF_EXTRACTS) { 92356c1817dSJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 92456c1817dSJun Yang return -EINVAL; 9255f176728SJun Yang } 9265f176728SJun Yang 92756c1817dSJun Yang if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) { 92856c1817dSJun Yang offset = key_profile->ip_addr_extract_off; 92956c1817dSJun Yang pos = key_profile->ip_addr_extract_pos; 93056c1817dSJun Yang key_profile->ip_addr_extract_pos++; 93156c1817dSJun Yang key_profile->ip_addr_extract_off += field_size; 93256c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 93356c1817dSJun Yang ret = dpaa2_flow_qos_rule_insert_hole(priv, 93456c1817dSJun Yang offset, field_size); 9355f176728SJun Yang } else { 93656c1817dSJun Yang ret = dpaa2_flow_fs_rule_insert_hole(priv, 93756c1817dSJun Yang offset, field_size, tc_id); 93856c1817dSJun Yang } 93956c1817dSJun Yang if (ret) 94056c1817dSJun Yang return ret; 94156c1817dSJun Yang } else { 94256c1817dSJun Yang pos = num; 9435f176728SJun Yang } 9445f176728SJun Yang 94556c1817dSJun Yang if (pos > 0) { 94656c1817dSJun Yang key_profile->key_offset[pos] = 94756c1817dSJun Yang key_profile->key_offset[pos - 1] + 94856c1817dSJun Yang key_profile->key_size[pos - 1]; 9495f176728SJun Yang } else { 95056c1817dSJun Yang key_profile->key_offset[pos] = 0; 9515f176728SJun Yang } 95256c1817dSJun Yang 95356c1817dSJun Yang key_profile->key_size[pos] = field_size; 954200a33e4SJun Yang key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY; 95556c1817dSJun Yang key_profile->prot_field[pos].prot = prot; 95656c1817dSJun Yang key_profile->prot_field[pos].key_field = field; 95756c1817dSJun Yang key_profile->num++; 95856c1817dSJun Yang 95956c1817dSJun Yang if (insert_offset) 96056c1817dSJun Yang *insert_offset = key_profile->key_offset[pos]; 96156c1817dSJun Yang 96256c1817dSJun Yang if (dpaa2_flow_l4_src_port_extract(prot, field)) { 96356c1817dSJun Yang key_profile->l4_src_port_present = 1; 96456c1817dSJun Yang key_profile->l4_src_port_pos = pos; 96556c1817dSJun Yang key_profile->l4_src_port_offset = 96656c1817dSJun Yang key_profile->key_offset[pos]; 96756c1817dSJun Yang } else if (dpaa2_flow_l4_dst_port_extract(prot, field)) { 96856c1817dSJun Yang key_profile->l4_dst_port_present = 1; 96956c1817dSJun Yang key_profile->l4_dst_port_pos = pos; 97056c1817dSJun Yang key_profile->l4_dst_port_offset = 97156c1817dSJun Yang key_profile->key_offset[pos]; 9725f176728SJun Yang } 97356c1817dSJun Yang key_profile->key_max_size += field_size; 97456c1817dSJun Yang 97556c1817dSJun Yang return pos; 9765f176728SJun Yang } 97756c1817dSJun Yang 97856c1817dSJun Yang static int 979200a33e4SJun Yang dpaa2_flow_faf_add_hdr(int faf_byte, 980200a33e4SJun Yang struct dpaa2_dev_priv *priv, 981200a33e4SJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id, 982200a33e4SJun Yang int *insert_offset) 983200a33e4SJun Yang { 984200a33e4SJun Yang int pos, i, offset; 985200a33e4SJun Yang struct dpaa2_key_extract *key_extract; 986200a33e4SJun Yang struct dpkg_profile_cfg *dpkg; 987200a33e4SJun Yang struct dpkg_extract *extracts; 988200a33e4SJun Yang 989200a33e4SJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 990200a33e4SJun Yang key_extract = &priv->extract.qos_key_extract; 991200a33e4SJun Yang else 992200a33e4SJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 993200a33e4SJun Yang 994200a33e4SJun Yang dpkg = &key_extract->dpkg; 995200a33e4SJun Yang extracts = dpkg->extracts; 996200a33e4SJun Yang 997200a33e4SJun Yang if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) { 998200a33e4SJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 999200a33e4SJun Yang return -EINVAL; 1000200a33e4SJun Yang } 1001200a33e4SJun Yang 1002200a33e4SJun Yang pos = dpaa2_flow_faf_advance(priv, 1003200a33e4SJun Yang faf_byte, dist_type, tc_id, 1004200a33e4SJun Yang insert_offset); 1005200a33e4SJun Yang if (pos < 0) 1006200a33e4SJun Yang return pos; 1007200a33e4SJun Yang 1008200a33e4SJun Yang if (pos != dpkg->num_extracts) { 1009200a33e4SJun Yang /* Not the last pos, must have IP address extract.*/ 1010200a33e4SJun Yang for (i = dpkg->num_extracts - 1; i >= pos; i--) { 1011200a33e4SJun Yang memcpy(&extracts[i + 1], 1012200a33e4SJun Yang &extracts[i], sizeof(struct dpkg_extract)); 1013200a33e4SJun Yang } 1014200a33e4SJun Yang } 1015200a33e4SJun Yang 1016200a33e4SJun Yang offset = DPAA2_FAFE_PSR_OFFSET + faf_byte; 1017200a33e4SJun Yang 1018200a33e4SJun Yang extracts[pos].type = DPKG_EXTRACT_FROM_PARSE; 1019200a33e4SJun Yang extracts[pos].extract.from_parse.offset = offset; 1020200a33e4SJun Yang extracts[pos].extract.from_parse.size = 1; 1021200a33e4SJun Yang 1022200a33e4SJun Yang dpkg->num_extracts++; 1023200a33e4SJun Yang 1024200a33e4SJun Yang return 0; 1025200a33e4SJun Yang } 1026200a33e4SJun Yang 1027200a33e4SJun Yang static int 102839c8044fSJun Yang dpaa2_flow_pr_add_hdr(uint32_t pr_offset, 102939c8044fSJun Yang uint32_t pr_size, struct dpaa2_dev_priv *priv, 103039c8044fSJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id, 103139c8044fSJun Yang int *insert_offset) 103239c8044fSJun Yang { 103339c8044fSJun Yang int pos, i; 103439c8044fSJun Yang struct dpaa2_key_extract *key_extract; 103539c8044fSJun Yang struct dpkg_profile_cfg *dpkg; 103639c8044fSJun Yang struct dpkg_extract *extracts; 103739c8044fSJun Yang 103839c8044fSJun Yang if ((pr_offset + pr_size) > DPAA2_FAPR_SIZE) { 103939c8044fSJun Yang DPAA2_PMD_ERR("PR extracts(%d:%d) overflow", 104039c8044fSJun Yang pr_offset, pr_size); 104139c8044fSJun Yang return -EINVAL; 104239c8044fSJun Yang } 104339c8044fSJun Yang 104439c8044fSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 104539c8044fSJun Yang key_extract = &priv->extract.qos_key_extract; 104639c8044fSJun Yang else 104739c8044fSJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 104839c8044fSJun Yang 104939c8044fSJun Yang dpkg = &key_extract->dpkg; 105039c8044fSJun Yang extracts = dpkg->extracts; 105139c8044fSJun Yang 105239c8044fSJun Yang if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) { 105339c8044fSJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 105439c8044fSJun Yang return -EINVAL; 105539c8044fSJun Yang } 105639c8044fSJun Yang 105739c8044fSJun Yang pos = dpaa2_flow_pr_advance(priv, 105839c8044fSJun Yang pr_offset, pr_size, dist_type, tc_id, 105939c8044fSJun Yang insert_offset); 106039c8044fSJun Yang if (pos < 0) 106139c8044fSJun Yang return pos; 106239c8044fSJun Yang 106339c8044fSJun Yang if (pos != dpkg->num_extracts) { 106439c8044fSJun Yang /* Not the last pos, must have IP address extract.*/ 106539c8044fSJun Yang for (i = dpkg->num_extracts - 1; i >= pos; i--) { 106639c8044fSJun Yang memcpy(&extracts[i + 1], 106739c8044fSJun Yang &extracts[i], sizeof(struct dpkg_extract)); 106839c8044fSJun Yang } 106939c8044fSJun Yang } 107039c8044fSJun Yang 107139c8044fSJun Yang extracts[pos].type = DPKG_EXTRACT_FROM_PARSE; 107239c8044fSJun Yang extracts[pos].extract.from_parse.offset = pr_offset; 107339c8044fSJun Yang extracts[pos].extract.from_parse.size = pr_size; 107439c8044fSJun Yang 107539c8044fSJun Yang dpkg->num_extracts++; 107639c8044fSJun Yang 107739c8044fSJun Yang return 0; 107839c8044fSJun Yang } 107939c8044fSJun Yang 108039c8044fSJun Yang static int 108156c1817dSJun Yang dpaa2_flow_extract_add_hdr(enum net_prot prot, 108256c1817dSJun Yang uint32_t field, uint8_t field_size, 108356c1817dSJun Yang struct dpaa2_dev_priv *priv, 108456c1817dSJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id, 108556c1817dSJun Yang int *insert_offset) 108656c1817dSJun Yang { 108756c1817dSJun Yang int pos, i; 108856c1817dSJun Yang struct dpaa2_key_extract *key_extract; 108956c1817dSJun Yang struct dpkg_profile_cfg *dpkg; 109056c1817dSJun Yang struct dpkg_extract *extracts; 109156c1817dSJun Yang 109256c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 109356c1817dSJun Yang key_extract = &priv->extract.qos_key_extract; 109456c1817dSJun Yang else 109556c1817dSJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 109656c1817dSJun Yang 109756c1817dSJun Yang dpkg = &key_extract->dpkg; 109856c1817dSJun Yang extracts = dpkg->extracts; 109956c1817dSJun Yang 110056c1817dSJun Yang if (dpaa2_flow_ip_address_extract(prot, field)) { 110156c1817dSJun Yang DPAA2_PMD_ERR("%s only for none IP address extract", 110256c1817dSJun Yang __func__); 110356c1817dSJun Yang return -EINVAL; 11045f176728SJun Yang } 110556c1817dSJun Yang 110656c1817dSJun Yang if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) { 110756c1817dSJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 110856c1817dSJun Yang return -EINVAL; 110956c1817dSJun Yang } 111056c1817dSJun Yang 111156c1817dSJun Yang pos = dpaa2_flow_key_profile_advance(prot, 111256c1817dSJun Yang field, field_size, priv, 111356c1817dSJun Yang dist_type, tc_id, 111456c1817dSJun Yang insert_offset); 111556c1817dSJun Yang if (pos < 0) 111656c1817dSJun Yang return pos; 111756c1817dSJun Yang 111856c1817dSJun Yang if (pos != dpkg->num_extracts) { 111956c1817dSJun Yang /* Not the last pos, must have IP address extract.*/ 112056c1817dSJun Yang for (i = dpkg->num_extracts - 1; i >= pos; i--) { 112156c1817dSJun Yang memcpy(&extracts[i + 1], 112256c1817dSJun Yang &extracts[i], sizeof(struct dpkg_extract)); 11235f176728SJun Yang } 11245f176728SJun Yang } 11255f176728SJun Yang 112656c1817dSJun Yang extracts[pos].type = DPKG_EXTRACT_FROM_HDR; 112756c1817dSJun Yang extracts[pos].extract.from_hdr.prot = prot; 112856c1817dSJun Yang extracts[pos].extract.from_hdr.type = DPKG_FULL_FIELD; 112956c1817dSJun Yang extracts[pos].extract.from_hdr.field = field; 11305f176728SJun Yang 11315f176728SJun Yang dpkg->num_extracts++; 11325f176728SJun Yang 11335f176728SJun Yang return 0; 11345f176728SJun Yang } 11355f176728SJun Yang 113656c1817dSJun Yang static int 1137e21bff64SJun Yang dpaa2_flow_extract_new_raw(struct dpaa2_dev_priv *priv, 1138e21bff64SJun Yang int offset, int size, 1139e21bff64SJun Yang enum dpaa2_flow_dist_type dist_type, int tc_id) 11403f881f8dSNipun Gupta { 1141e21bff64SJun Yang struct dpaa2_key_extract *key_extract; 1142e21bff64SJun Yang struct dpkg_profile_cfg *dpkg; 1143e21bff64SJun Yang struct dpaa2_key_profile *key_profile; 1144e21bff64SJun Yang int last_extract_size, index, pos, item_size; 1145e21bff64SJun Yang uint8_t num_extracts; 1146e21bff64SJun Yang uint32_t field; 11473f881f8dSNipun Gupta 1148e21bff64SJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 1149e21bff64SJun Yang key_extract = &priv->extract.qos_key_extract; 1150e21bff64SJun Yang else 1151e21bff64SJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 1152e21bff64SJun Yang 1153e21bff64SJun Yang dpkg = &key_extract->dpkg; 1154e21bff64SJun Yang key_profile = &key_extract->key_profile; 1155e21bff64SJun Yang 1156e21bff64SJun Yang key_profile->raw_region.raw_start = 0; 1157e21bff64SJun Yang key_profile->raw_region.raw_size = 0; 11583f881f8dSNipun Gupta 11593f881f8dSNipun Gupta last_extract_size = (size % DPAA2_FLOW_MAX_KEY_SIZE); 1160e21bff64SJun Yang num_extracts = (size / DPAA2_FLOW_MAX_KEY_SIZE); 11613f881f8dSNipun Gupta if (last_extract_size) 1162e21bff64SJun Yang num_extracts++; 11633f881f8dSNipun Gupta else 11643f881f8dSNipun Gupta last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE; 11653f881f8dSNipun Gupta 1166e21bff64SJun Yang for (index = 0; index < num_extracts; index++) { 1167e21bff64SJun Yang if (index == num_extracts - 1) 1168e21bff64SJun Yang item_size = last_extract_size; 11693f881f8dSNipun Gupta else 1170e21bff64SJun Yang item_size = DPAA2_FLOW_MAX_KEY_SIZE; 1171e21bff64SJun Yang field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT; 1172e21bff64SJun Yang field |= item_size; 1173e21bff64SJun Yang 1174e21bff64SJun Yang pos = dpaa2_flow_key_profile_advance(NET_PROT_PAYLOAD, 1175e21bff64SJun Yang field, item_size, priv, dist_type, 1176e21bff64SJun Yang tc_id, NULL); 1177e21bff64SJun Yang if (pos < 0) 1178e21bff64SJun Yang return pos; 1179e21bff64SJun Yang 1180e21bff64SJun Yang dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA; 1181e21bff64SJun Yang dpkg->extracts[pos].extract.from_data.size = item_size; 1182e21bff64SJun Yang dpkg->extracts[pos].extract.from_data.offset = offset; 1183e21bff64SJun Yang 1184e21bff64SJun Yang if (index == 0) { 1185e21bff64SJun Yang key_profile->raw_extract_pos = pos; 1186e21bff64SJun Yang key_profile->raw_extract_off = 1187e21bff64SJun Yang key_profile->key_offset[pos]; 1188e21bff64SJun Yang key_profile->raw_region.raw_start = offset; 1189e21bff64SJun Yang } 1190e21bff64SJun Yang key_profile->raw_extract_num++; 1191e21bff64SJun Yang key_profile->raw_region.raw_size += 1192e21bff64SJun Yang key_profile->key_size[pos]; 1193e21bff64SJun Yang 1194e21bff64SJun Yang offset += item_size; 1195e21bff64SJun Yang dpkg->num_extracts++; 11963f881f8dSNipun Gupta } 11973f881f8dSNipun Gupta 11983f881f8dSNipun Gupta return 0; 11993f881f8dSNipun Gupta } 12003f881f8dSNipun Gupta 1201e21bff64SJun Yang static int 1202e21bff64SJun Yang dpaa2_flow_extract_add_raw(struct dpaa2_dev_priv *priv, 1203e21bff64SJun Yang int offset, int size, enum dpaa2_flow_dist_type dist_type, 1204e21bff64SJun Yang int tc_id, int *recfg) 1205e21bff64SJun Yang { 1206e21bff64SJun Yang struct dpaa2_key_profile *key_profile; 1207e21bff64SJun Yang struct dpaa2_raw_region *raw_region; 1208e21bff64SJun Yang int end = offset + size, ret = 0, extract_extended, sz_extend; 1209e21bff64SJun Yang int start_cmp, end_cmp, new_size, index, pos, end_pos; 1210e21bff64SJun Yang int last_extract_size, item_size, num_extracts, bk_num = 0; 1211e21bff64SJun Yang struct dpkg_extract extract_bk[DPKG_MAX_NUM_OF_EXTRACTS]; 1212e21bff64SJun Yang uint8_t key_offset_bk[DPKG_MAX_NUM_OF_EXTRACTS]; 1213e21bff64SJun Yang uint8_t key_size_bk[DPKG_MAX_NUM_OF_EXTRACTS]; 1214e21bff64SJun Yang struct key_prot_field prot_field_bk[DPKG_MAX_NUM_OF_EXTRACTS]; 1215e21bff64SJun Yang struct dpaa2_raw_region raw_hole; 1216e21bff64SJun Yang struct dpkg_profile_cfg *dpkg; 1217e21bff64SJun Yang enum net_prot prot; 1218e21bff64SJun Yang uint32_t field; 1219e21bff64SJun Yang 1220e21bff64SJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 1221e21bff64SJun Yang key_profile = &priv->extract.qos_key_extract.key_profile; 1222e21bff64SJun Yang dpkg = &priv->extract.qos_key_extract.dpkg; 1223e21bff64SJun Yang } else { 1224e21bff64SJun Yang key_profile = &priv->extract.tc_key_extract[tc_id].key_profile; 1225e21bff64SJun Yang dpkg = &priv->extract.tc_key_extract[tc_id].dpkg; 1226e21bff64SJun Yang } 1227e21bff64SJun Yang 1228e21bff64SJun Yang raw_region = &key_profile->raw_region; 1229e21bff64SJun Yang if (!raw_region->raw_size) { 1230e21bff64SJun Yang /* New RAW region*/ 1231e21bff64SJun Yang ret = dpaa2_flow_extract_new_raw(priv, offset, size, 1232e21bff64SJun Yang dist_type, tc_id); 1233e21bff64SJun Yang if (!ret && recfg) 1234e21bff64SJun Yang (*recfg) |= dist_type; 1235e21bff64SJun Yang 1236e21bff64SJun Yang return ret; 1237e21bff64SJun Yang } 1238e21bff64SJun Yang start_cmp = raw_region->raw_start; 1239e21bff64SJun Yang end_cmp = raw_region->raw_start + raw_region->raw_size; 1240e21bff64SJun Yang 1241e21bff64SJun Yang if (offset >= start_cmp && end <= end_cmp) 1242e21bff64SJun Yang return 0; 1243e21bff64SJun Yang 1244e21bff64SJun Yang sz_extend = 0; 1245e21bff64SJun Yang new_size = raw_region->raw_size; 1246e21bff64SJun Yang if (offset < start_cmp) { 1247e21bff64SJun Yang sz_extend += start_cmp - offset; 1248e21bff64SJun Yang new_size += (start_cmp - offset); 1249e21bff64SJun Yang } 1250e21bff64SJun Yang if (end > end_cmp) { 1251e21bff64SJun Yang sz_extend += end - end_cmp; 1252e21bff64SJun Yang new_size += (end - end_cmp); 1253e21bff64SJun Yang } 1254e21bff64SJun Yang 1255e21bff64SJun Yang last_extract_size = (new_size % DPAA2_FLOW_MAX_KEY_SIZE); 1256e21bff64SJun Yang num_extracts = (new_size / DPAA2_FLOW_MAX_KEY_SIZE); 1257e21bff64SJun Yang if (last_extract_size) 1258e21bff64SJun Yang num_extracts++; 1259e21bff64SJun Yang else 1260e21bff64SJun Yang last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE; 1261e21bff64SJun Yang 1262e21bff64SJun Yang if ((key_profile->num + num_extracts - 1263e21bff64SJun Yang key_profile->raw_extract_num) >= 1264e21bff64SJun Yang DPKG_MAX_NUM_OF_EXTRACTS) { 1265e21bff64SJun Yang DPAA2_PMD_ERR("%s Failed to expand raw extracts", 1266e21bff64SJun Yang __func__); 1267e21bff64SJun Yang return -EINVAL; 1268e21bff64SJun Yang } 1269e21bff64SJun Yang 1270e21bff64SJun Yang if (offset < start_cmp) { 1271e21bff64SJun Yang raw_hole.raw_start = key_profile->raw_extract_off; 1272e21bff64SJun Yang raw_hole.raw_size = start_cmp - offset; 1273e21bff64SJun Yang raw_region->raw_start = offset; 1274e21bff64SJun Yang raw_region->raw_size += start_cmp - offset; 1275e21bff64SJun Yang 1276e21bff64SJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 1277e21bff64SJun Yang ret = dpaa2_flow_qos_rule_insert_hole(priv, 1278e21bff64SJun Yang raw_hole.raw_start, 1279e21bff64SJun Yang raw_hole.raw_size); 1280e21bff64SJun Yang if (ret) 1281e21bff64SJun Yang return ret; 1282e21bff64SJun Yang } 1283e21bff64SJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 1284e21bff64SJun Yang ret = dpaa2_flow_fs_rule_insert_hole(priv, 1285e21bff64SJun Yang raw_hole.raw_start, 1286e21bff64SJun Yang raw_hole.raw_size, tc_id); 1287e21bff64SJun Yang if (ret) 1288e21bff64SJun Yang return ret; 1289e21bff64SJun Yang } 1290e21bff64SJun Yang } 1291e21bff64SJun Yang 1292e21bff64SJun Yang if (end > end_cmp) { 1293e21bff64SJun Yang raw_hole.raw_start = 1294e21bff64SJun Yang key_profile->raw_extract_off + 1295e21bff64SJun Yang raw_region->raw_size; 1296e21bff64SJun Yang raw_hole.raw_size = end - end_cmp; 1297e21bff64SJun Yang raw_region->raw_size += end - end_cmp; 1298e21bff64SJun Yang 1299e21bff64SJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 1300e21bff64SJun Yang ret = dpaa2_flow_qos_rule_insert_hole(priv, 1301e21bff64SJun Yang raw_hole.raw_start, 1302e21bff64SJun Yang raw_hole.raw_size); 1303e21bff64SJun Yang if (ret) 1304e21bff64SJun Yang return ret; 1305e21bff64SJun Yang } 1306e21bff64SJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 1307e21bff64SJun Yang ret = dpaa2_flow_fs_rule_insert_hole(priv, 1308e21bff64SJun Yang raw_hole.raw_start, 1309e21bff64SJun Yang raw_hole.raw_size, tc_id); 1310e21bff64SJun Yang if (ret) 1311e21bff64SJun Yang return ret; 1312e21bff64SJun Yang } 1313e21bff64SJun Yang } 1314e21bff64SJun Yang 1315e21bff64SJun Yang end_pos = key_profile->raw_extract_pos + 1316e21bff64SJun Yang key_profile->raw_extract_num; 1317e21bff64SJun Yang if (key_profile->num > end_pos) { 1318e21bff64SJun Yang bk_num = key_profile->num - end_pos; 1319e21bff64SJun Yang memcpy(extract_bk, &dpkg->extracts[end_pos], 1320e21bff64SJun Yang bk_num * sizeof(struct dpkg_extract)); 1321e21bff64SJun Yang memcpy(key_offset_bk, &key_profile->key_offset[end_pos], 1322e21bff64SJun Yang bk_num * sizeof(uint8_t)); 1323e21bff64SJun Yang memcpy(key_size_bk, &key_profile->key_size[end_pos], 1324e21bff64SJun Yang bk_num * sizeof(uint8_t)); 1325e21bff64SJun Yang memcpy(prot_field_bk, &key_profile->prot_field[end_pos], 1326e21bff64SJun Yang bk_num * sizeof(struct key_prot_field)); 1327e21bff64SJun Yang 1328e21bff64SJun Yang for (index = 0; index < bk_num; index++) { 1329e21bff64SJun Yang key_offset_bk[index] += sz_extend; 1330e21bff64SJun Yang prot = prot_field_bk[index].prot; 1331e21bff64SJun Yang field = prot_field_bk[index].key_field; 1332e21bff64SJun Yang if (dpaa2_flow_l4_src_port_extract(prot, 1333e21bff64SJun Yang field)) { 1334e21bff64SJun Yang key_profile->l4_src_port_present = 1; 1335e21bff64SJun Yang key_profile->l4_src_port_pos = end_pos + index; 1336e21bff64SJun Yang key_profile->l4_src_port_offset = 1337e21bff64SJun Yang key_offset_bk[index]; 1338e21bff64SJun Yang } else if (dpaa2_flow_l4_dst_port_extract(prot, 1339e21bff64SJun Yang field)) { 1340e21bff64SJun Yang key_profile->l4_dst_port_present = 1; 1341e21bff64SJun Yang key_profile->l4_dst_port_pos = end_pos + index; 1342e21bff64SJun Yang key_profile->l4_dst_port_offset = 1343e21bff64SJun Yang key_offset_bk[index]; 1344e21bff64SJun Yang } 1345e21bff64SJun Yang } 1346e21bff64SJun Yang } 1347e21bff64SJun Yang 1348e21bff64SJun Yang pos = key_profile->raw_extract_pos; 1349e21bff64SJun Yang 1350e21bff64SJun Yang for (index = 0; index < num_extracts; index++) { 1351e21bff64SJun Yang if (index == num_extracts - 1) 1352e21bff64SJun Yang item_size = last_extract_size; 1353e21bff64SJun Yang else 1354e21bff64SJun Yang item_size = DPAA2_FLOW_MAX_KEY_SIZE; 1355e21bff64SJun Yang field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT; 1356e21bff64SJun Yang field |= item_size; 1357e21bff64SJun Yang 1358e21bff64SJun Yang if (pos > 0) { 1359e21bff64SJun Yang key_profile->key_offset[pos] = 1360e21bff64SJun Yang key_profile->key_offset[pos - 1] + 1361e21bff64SJun Yang key_profile->key_size[pos - 1]; 1362e21bff64SJun Yang } else { 1363e21bff64SJun Yang key_profile->key_offset[pos] = 0; 1364e21bff64SJun Yang } 1365e21bff64SJun Yang key_profile->key_size[pos] = item_size; 1366200a33e4SJun Yang key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY; 1367e21bff64SJun Yang key_profile->prot_field[pos].prot = NET_PROT_PAYLOAD; 1368e21bff64SJun Yang key_profile->prot_field[pos].key_field = field; 1369e21bff64SJun Yang 1370e21bff64SJun Yang dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA; 1371e21bff64SJun Yang dpkg->extracts[pos].extract.from_data.size = item_size; 1372e21bff64SJun Yang dpkg->extracts[pos].extract.from_data.offset = offset; 1373e21bff64SJun Yang offset += item_size; 1374e21bff64SJun Yang pos++; 1375e21bff64SJun Yang } 1376e21bff64SJun Yang 1377e21bff64SJun Yang if (bk_num) { 1378e21bff64SJun Yang memcpy(&dpkg->extracts[pos], extract_bk, 1379e21bff64SJun Yang bk_num * sizeof(struct dpkg_extract)); 1380e21bff64SJun Yang memcpy(&key_profile->key_offset[end_pos], 1381e21bff64SJun Yang key_offset_bk, bk_num * sizeof(uint8_t)); 1382e21bff64SJun Yang memcpy(&key_profile->key_size[end_pos], 1383e21bff64SJun Yang key_size_bk, bk_num * sizeof(uint8_t)); 1384e21bff64SJun Yang memcpy(&key_profile->prot_field[end_pos], 1385e21bff64SJun Yang prot_field_bk, bk_num * sizeof(struct key_prot_field)); 1386e21bff64SJun Yang } 1387e21bff64SJun Yang 1388e21bff64SJun Yang extract_extended = num_extracts - key_profile->raw_extract_num; 1389e21bff64SJun Yang if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) { 1390e21bff64SJun Yang key_profile->ip_addr_extract_pos += extract_extended; 1391e21bff64SJun Yang key_profile->ip_addr_extract_off += sz_extend; 1392e21bff64SJun Yang } 1393e21bff64SJun Yang key_profile->raw_extract_num = num_extracts; 1394e21bff64SJun Yang key_profile->num += extract_extended; 1395e21bff64SJun Yang key_profile->key_max_size += sz_extend; 1396e21bff64SJun Yang 1397e21bff64SJun Yang dpkg->num_extracts += extract_extended; 1398e21bff64SJun Yang if (!ret && recfg) 1399e21bff64SJun Yang (*recfg) |= dist_type; 1400e21bff64SJun Yang 1401e21bff64SJun Yang return ret; 1402e21bff64SJun Yang } 1403e21bff64SJun Yang 14045f176728SJun Yang static inline int 140556c1817dSJun Yang dpaa2_flow_extract_search(struct dpaa2_key_profile *key_profile, 1406200a33e4SJun Yang enum key_prot_type type, enum net_prot prot, uint32_t key_field) 14075f176728SJun Yang { 140856c1817dSJun Yang int pos; 140956c1817dSJun Yang struct key_prot_field *prot_field; 141056c1817dSJun Yang 141156c1817dSJun Yang if (dpaa2_flow_ip_address_extract(prot, key_field)) { 141256c1817dSJun Yang DPAA2_PMD_ERR("%s only for none IP address extract", 141356c1817dSJun Yang __func__); 141456c1817dSJun Yang return -EINVAL; 14155f176728SJun Yang } 14165f176728SJun Yang 141756c1817dSJun Yang prot_field = key_profile->prot_field; 141856c1817dSJun Yang for (pos = 0; pos < key_profile->num; pos++) { 1419200a33e4SJun Yang if (type == DPAA2_NET_PROT_KEY && 1420200a33e4SJun Yang prot_field[pos].prot == prot && 1421200a33e4SJun Yang prot_field[pos].key_field == key_field && 1422200a33e4SJun Yang prot_field[pos].type == type) 1423200a33e4SJun Yang return pos; 1424200a33e4SJun Yang else if (type == DPAA2_FAF_KEY && 1425200a33e4SJun Yang prot_field[pos].key_field == key_field && 1426200a33e4SJun Yang prot_field[pos].type == type) 142756c1817dSJun Yang return pos; 142839c8044fSJun Yang else if (type == DPAA2_PR_KEY && 142939c8044fSJun Yang prot_field[pos].key_field == key_field && 143039c8044fSJun Yang prot_field[pos].type == type) 143139c8044fSJun Yang return pos; 143256c1817dSJun Yang } 14335f176728SJun Yang 1434200a33e4SJun Yang if (type == DPAA2_NET_PROT_KEY && 1435200a33e4SJun Yang dpaa2_flow_l4_src_port_extract(prot, key_field)) { 143656c1817dSJun Yang if (key_profile->l4_src_port_present) 143756c1817dSJun Yang return key_profile->l4_src_port_pos; 1438200a33e4SJun Yang } else if (type == DPAA2_NET_PROT_KEY && 1439200a33e4SJun Yang dpaa2_flow_l4_dst_port_extract(prot, key_field)) { 144056c1817dSJun Yang if (key_profile->l4_dst_port_present) 144156c1817dSJun Yang return key_profile->l4_dst_port_pos; 144256c1817dSJun Yang } 144356c1817dSJun Yang 144456c1817dSJun Yang return -ENXIO; 144556c1817dSJun Yang } 144656c1817dSJun Yang 144756c1817dSJun Yang static inline int 144856c1817dSJun Yang dpaa2_flow_extract_key_offset(struct dpaa2_key_profile *key_profile, 1449200a33e4SJun Yang enum key_prot_type type, enum net_prot prot, uint32_t key_field) 14505f176728SJun Yang { 14515f176728SJun Yang int i; 14525f176728SJun Yang 1453200a33e4SJun Yang i = dpaa2_flow_extract_search(key_profile, type, prot, key_field); 145456c1817dSJun Yang if (i >= 0) 145556c1817dSJun Yang return key_profile->key_offset[i]; 145656c1817dSJun Yang else 14575f176728SJun Yang return i; 14585f176728SJun Yang } 14595f176728SJun Yang 14605f176728SJun Yang static int 1461200a33e4SJun Yang dpaa2_flow_faf_add_rule(struct dpaa2_dev_priv *priv, 146256c1817dSJun Yang struct dpaa2_dev_flow *flow, 1463200a33e4SJun Yang enum dpaa2_rx_faf_offset faf_bit_off, 146456c1817dSJun Yang int group, 146556c1817dSJun Yang enum dpaa2_flow_dist_type dist_type) 14665f176728SJun Yang { 14675f176728SJun Yang int offset; 146856c1817dSJun Yang uint8_t *key_addr; 146956c1817dSJun Yang uint8_t *mask_addr; 147056c1817dSJun Yang struct dpaa2_key_extract *key_extract; 147156c1817dSJun Yang struct dpaa2_key_profile *key_profile; 1472200a33e4SJun Yang uint8_t faf_byte = faf_bit_off / 8; 1473200a33e4SJun Yang uint8_t faf_bit_in_byte = faf_bit_off % 8; 14745f176728SJun Yang 1475200a33e4SJun Yang faf_bit_in_byte = 7 - faf_bit_in_byte; 14765f176728SJun Yang 147756c1817dSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 147856c1817dSJun Yang key_extract = &priv->extract.qos_key_extract; 147956c1817dSJun Yang key_profile = &key_extract->key_profile; 148056c1817dSJun Yang 148156c1817dSJun Yang offset = dpaa2_flow_extract_key_offset(key_profile, 1482200a33e4SJun Yang DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte); 14835f176728SJun Yang if (offset < 0) { 148456c1817dSJun Yang DPAA2_PMD_ERR("%s QoS key extract failed", __func__); 148556c1817dSJun Yang return -EINVAL; 14865f176728SJun Yang } 148756c1817dSJun Yang key_addr = flow->qos_key_addr + offset; 148856c1817dSJun Yang mask_addr = flow->qos_mask_addr + offset; 1489200a33e4SJun Yang 1490200a33e4SJun Yang if (!(*key_addr) && 1491200a33e4SJun Yang key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 1492200a33e4SJun Yang flow->qos_rule_size++; 1493200a33e4SJun Yang 1494200a33e4SJun Yang *key_addr |= (1 << faf_bit_in_byte); 1495200a33e4SJun Yang *mask_addr |= (1 << faf_bit_in_byte); 14965f176728SJun Yang } 14975f176728SJun Yang 149856c1817dSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 149956c1817dSJun Yang key_extract = &priv->extract.tc_key_extract[group]; 150056c1817dSJun Yang key_profile = &key_extract->key_profile; 150156c1817dSJun Yang 150256c1817dSJun Yang offset = dpaa2_flow_extract_key_offset(key_profile, 1503200a33e4SJun Yang DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte); 15045f176728SJun Yang if (offset < 0) { 150556c1817dSJun Yang DPAA2_PMD_ERR("%s TC[%d] key extract failed", 150656c1817dSJun Yang __func__, group); 150756c1817dSJun Yang return -EINVAL; 15085f176728SJun Yang } 150956c1817dSJun Yang key_addr = flow->fs_key_addr + offset; 151056c1817dSJun Yang mask_addr = flow->fs_mask_addr + offset; 15115f176728SJun Yang 1512200a33e4SJun Yang if (!(*key_addr) && 1513200a33e4SJun Yang key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 1514200a33e4SJun Yang flow->fs_rule_size++; 1515200a33e4SJun Yang 1516200a33e4SJun Yang *key_addr |= (1 << faf_bit_in_byte); 1517200a33e4SJun Yang *mask_addr |= (1 << faf_bit_in_byte); 15185f176728SJun Yang } 15195f176728SJun Yang 15205f176728SJun Yang return 0; 15215f176728SJun Yang } 15225f176728SJun Yang 15235f176728SJun Yang static inline int 152439c8044fSJun Yang dpaa2_flow_pr_rule_data_set(struct dpaa2_dev_flow *flow, 152539c8044fSJun Yang struct dpaa2_key_profile *key_profile, 152639c8044fSJun Yang uint32_t pr_offset, uint32_t pr_size, 152739c8044fSJun Yang const void *key, const void *mask, 152839c8044fSJun Yang enum dpaa2_flow_dist_type dist_type) 152939c8044fSJun Yang { 153039c8044fSJun Yang int offset; 153139c8044fSJun Yang uint32_t pr_field = pr_offset << 16 | pr_size; 153239c8044fSJun Yang 153339c8044fSJun Yang offset = dpaa2_flow_extract_key_offset(key_profile, 153439c8044fSJun Yang DPAA2_PR_KEY, NET_PROT_NONE, pr_field); 153539c8044fSJun Yang if (offset < 0) { 153639c8044fSJun Yang DPAA2_PMD_ERR("PR off(%d)/size(%d) does not exist!", 153739c8044fSJun Yang pr_offset, pr_size); 153839c8044fSJun Yang return -EINVAL; 153939c8044fSJun Yang } 154039c8044fSJun Yang 154139c8044fSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 154239c8044fSJun Yang memcpy((flow->qos_key_addr + offset), key, pr_size); 154339c8044fSJun Yang memcpy((flow->qos_mask_addr + offset), mask, pr_size); 154439c8044fSJun Yang if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 154539c8044fSJun Yang flow->qos_rule_size = offset + pr_size; 154639c8044fSJun Yang } 154739c8044fSJun Yang 154839c8044fSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 154939c8044fSJun Yang memcpy((flow->fs_key_addr + offset), key, pr_size); 155039c8044fSJun Yang memcpy((flow->fs_mask_addr + offset), mask, pr_size); 155139c8044fSJun Yang if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 155239c8044fSJun Yang flow->fs_rule_size = offset + pr_size; 155339c8044fSJun Yang } 155439c8044fSJun Yang 155539c8044fSJun Yang return 0; 155639c8044fSJun Yang } 155739c8044fSJun Yang 155839c8044fSJun Yang static inline int 155956c1817dSJun Yang dpaa2_flow_hdr_rule_data_set(struct dpaa2_dev_flow *flow, 156056c1817dSJun Yang struct dpaa2_key_profile *key_profile, 156156c1817dSJun Yang enum net_prot prot, uint32_t field, int size, 156256c1817dSJun Yang const void *key, const void *mask, 156356c1817dSJun Yang enum dpaa2_flow_dist_type dist_type) 15645f176728SJun Yang { 156556c1817dSJun Yang int offset; 15665f176728SJun Yang 156756c1817dSJun Yang if (dpaa2_flow_ip_address_extract(prot, field)) { 156856c1817dSJun Yang DPAA2_PMD_ERR("%s only for none IP address extract", 156956c1817dSJun Yang __func__); 157056c1817dSJun Yang return -EINVAL; 15715f176728SJun Yang } 1572d0a77dc3SJun Yang 157356c1817dSJun Yang offset = dpaa2_flow_extract_key_offset(key_profile, 1574200a33e4SJun Yang DPAA2_NET_PROT_KEY, prot, field); 157556c1817dSJun Yang if (offset < 0) { 157656c1817dSJun Yang DPAA2_PMD_ERR("P(%d)/F(%d) does not exist!", 157756c1817dSJun Yang prot, field); 157856c1817dSJun Yang return -EINVAL; 157956c1817dSJun Yang } 158056c1817dSJun Yang 158156c1817dSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 158256c1817dSJun Yang memcpy((flow->qos_key_addr + offset), key, size); 158356c1817dSJun Yang memcpy((flow->qos_mask_addr + offset), mask, size); 158456c1817dSJun Yang if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 158556c1817dSJun Yang flow->qos_rule_size = offset + size; 158656c1817dSJun Yang } 158756c1817dSJun Yang 158856c1817dSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 158956c1817dSJun Yang memcpy((flow->fs_key_addr + offset), key, size); 159056c1817dSJun Yang memcpy((flow->fs_mask_addr + offset), mask, size); 159156c1817dSJun Yang if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) 159256c1817dSJun Yang flow->fs_rule_size = offset + size; 159356c1817dSJun Yang } 15945f176728SJun Yang 15955f176728SJun Yang return 0; 15965f176728SJun Yang } 15975f176728SJun Yang 15985f176728SJun Yang static inline int 1599e21bff64SJun Yang dpaa2_flow_raw_rule_data_set(struct dpaa2_dev_flow *flow, 1600e21bff64SJun Yang struct dpaa2_key_profile *key_profile, 1601e21bff64SJun Yang uint32_t extract_offset, int size, 1602e21bff64SJun Yang const void *key, const void *mask, 1603e21bff64SJun Yang enum dpaa2_flow_dist_type dist_type) 16043f881f8dSNipun Gupta { 1605e21bff64SJun Yang int extract_size = size > DPAA2_FLOW_MAX_KEY_SIZE ? 1606e21bff64SJun Yang DPAA2_FLOW_MAX_KEY_SIZE : size; 1607e21bff64SJun Yang int offset, field; 16083f881f8dSNipun Gupta 1609e21bff64SJun Yang field = extract_offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT; 1610e21bff64SJun Yang field |= extract_size; 1611e21bff64SJun Yang offset = dpaa2_flow_extract_key_offset(key_profile, 1612200a33e4SJun Yang DPAA2_NET_PROT_KEY, NET_PROT_PAYLOAD, field); 1613e21bff64SJun Yang if (offset < 0) { 1614e21bff64SJun Yang DPAA2_PMD_ERR("offset(%d)/size(%d) raw extract failed", 1615e21bff64SJun Yang extract_offset, size); 1616e21bff64SJun Yang return -EINVAL; 1617e21bff64SJun Yang } 1618e21bff64SJun Yang 1619e21bff64SJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 1620e21bff64SJun Yang memcpy((flow->qos_key_addr + offset), key, size); 1621e21bff64SJun Yang memcpy((flow->qos_mask_addr + offset), mask, size); 1622e21bff64SJun Yang flow->qos_rule_size = offset + size; 1623e21bff64SJun Yang } 1624e21bff64SJun Yang 1625e21bff64SJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 1626e21bff64SJun Yang memcpy((flow->fs_key_addr + offset), key, size); 1627e21bff64SJun Yang memcpy((flow->fs_mask_addr + offset), mask, size); 1628e21bff64SJun Yang flow->fs_rule_size = offset + size; 1629e21bff64SJun Yang } 16303f881f8dSNipun Gupta 16313f881f8dSNipun Gupta return 0; 16323f881f8dSNipun Gupta } 16333f881f8dSNipun Gupta 1634fe2b986aSSunil Kumar Kori static int 163556c1817dSJun Yang dpaa2_flow_extract_support(const uint8_t *mask_src, 1636926c1279SJun Yang enum rte_flow_item_type type) 1637926c1279SJun Yang { 1638926c1279SJun Yang char mask[64]; 1639926c1279SJun Yang int i, size = 0; 1640926c1279SJun Yang const char *mask_support = 0; 1641926c1279SJun Yang 1642926c1279SJun Yang switch (type) { 1643926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_ETH: 1644926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_eth_mask; 1645926c1279SJun Yang size = sizeof(struct rte_flow_item_eth); 1646926c1279SJun Yang break; 1647926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_VLAN: 1648926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_vlan_mask; 1649926c1279SJun Yang size = sizeof(struct rte_flow_item_vlan); 1650926c1279SJun Yang break; 1651926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_IPV4: 1652926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_ipv4_mask; 1653926c1279SJun Yang size = sizeof(struct rte_flow_item_ipv4); 1654926c1279SJun Yang break; 1655926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_IPV6: 1656926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_ipv6_mask; 1657926c1279SJun Yang size = sizeof(struct rte_flow_item_ipv6); 1658926c1279SJun Yang break; 1659926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_ICMP: 1660926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_icmp_mask; 1661926c1279SJun Yang size = sizeof(struct rte_flow_item_icmp); 1662926c1279SJun Yang break; 1663926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_UDP: 1664926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_udp_mask; 1665926c1279SJun Yang size = sizeof(struct rte_flow_item_udp); 1666926c1279SJun Yang break; 1667926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_TCP: 1668926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_tcp_mask; 1669926c1279SJun Yang size = sizeof(struct rte_flow_item_tcp); 1670926c1279SJun Yang break; 16714cc5cf4aSJun Yang case RTE_FLOW_ITEM_TYPE_ESP: 16724cc5cf4aSJun Yang mask_support = (const char *)&dpaa2_flow_item_esp_mask; 16734cc5cf4aSJun Yang size = sizeof(struct rte_flow_item_esp); 16744cc5cf4aSJun Yang break; 16754cc5cf4aSJun Yang case RTE_FLOW_ITEM_TYPE_AH: 16764cc5cf4aSJun Yang mask_support = (const char *)&dpaa2_flow_item_ah_mask; 16774cc5cf4aSJun Yang size = sizeof(struct rte_flow_item_ah); 16784cc5cf4aSJun Yang break; 1679926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_SCTP: 1680926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_sctp_mask; 1681926c1279SJun Yang size = sizeof(struct rte_flow_item_sctp); 1682926c1279SJun Yang break; 1683926c1279SJun Yang case RTE_FLOW_ITEM_TYPE_GRE: 1684926c1279SJun Yang mask_support = (const char *)&dpaa2_flow_item_gre_mask; 1685926c1279SJun Yang size = sizeof(struct rte_flow_item_gre); 1686926c1279SJun Yang break; 168739c8044fSJun Yang case RTE_FLOW_ITEM_TYPE_VXLAN: 168839c8044fSJun Yang mask_support = (const char *)&dpaa2_flow_item_vxlan_mask; 168939c8044fSJun Yang size = sizeof(struct rte_flow_item_vxlan); 169039c8044fSJun Yang break; 1691a8a6b82eSJun Yang case RTE_FLOW_ITEM_TYPE_ECPRI: 1692a8a6b82eSJun Yang mask_support = (const char *)&dpaa2_flow_item_ecpri_mask; 1693a8a6b82eSJun Yang size = sizeof(struct rte_flow_item_ecpri); 1694a8a6b82eSJun Yang break; 1695146c745eSJun Yang case RTE_FLOW_ITEM_TYPE_GTP: 1696146c745eSJun Yang mask_support = (const char *)&dpaa2_flow_item_gtp_mask; 1697146c745eSJun Yang size = sizeof(struct rte_flow_item_gtp); 1698146c745eSJun Yang break; 1699926c1279SJun Yang default: 170056c1817dSJun Yang return -EINVAL; 1701926c1279SJun Yang } 1702926c1279SJun Yang 1703926c1279SJun Yang memcpy(mask, mask_support, size); 1704926c1279SJun Yang 1705926c1279SJun Yang for (i = 0; i < size; i++) 1706926c1279SJun Yang mask[i] = (mask[i] | mask_src[i]); 1707926c1279SJun Yang 1708926c1279SJun Yang if (memcmp(mask, mask_support, size)) 17094cc5cf4aSJun Yang return -ENOTSUP; 1710926c1279SJun Yang 1711926c1279SJun Yang return 0; 1712926c1279SJun Yang } 1713926c1279SJun Yang 1714926c1279SJun Yang static int 1715200a33e4SJun Yang dpaa2_flow_identify_by_faf(struct dpaa2_dev_priv *priv, 171656c1817dSJun Yang struct dpaa2_dev_flow *flow, 1717200a33e4SJun Yang enum dpaa2_rx_faf_offset faf_off, 171856c1817dSJun Yang enum dpaa2_flow_dist_type dist_type, 171956c1817dSJun Yang int group, int *recfg) 172056c1817dSJun Yang { 1721200a33e4SJun Yang int ret, index, local_cfg = 0; 172256c1817dSJun Yang struct dpaa2_key_extract *extract; 172356c1817dSJun Yang struct dpaa2_key_profile *key_profile; 1724200a33e4SJun Yang uint8_t faf_byte = faf_off / 8; 172556c1817dSJun Yang 172656c1817dSJun Yang if (dist_type & DPAA2_FLOW_QOS_TYPE) { 172756c1817dSJun Yang extract = &priv->extract.qos_key_extract; 172856c1817dSJun Yang key_profile = &extract->key_profile; 172956c1817dSJun Yang 173056c1817dSJun Yang index = dpaa2_flow_extract_search(key_profile, 1731200a33e4SJun Yang DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte); 173256c1817dSJun Yang if (index < 0) { 1733200a33e4SJun Yang ret = dpaa2_flow_faf_add_hdr(faf_byte, 1734200a33e4SJun Yang priv, DPAA2_FLOW_QOS_TYPE, group, 173556c1817dSJun Yang NULL); 173656c1817dSJun Yang if (ret) { 1737200a33e4SJun Yang DPAA2_PMD_ERR("QOS faf extract add failed"); 173856c1817dSJun Yang 173956c1817dSJun Yang return -EINVAL; 174056c1817dSJun Yang } 174156c1817dSJun Yang local_cfg |= DPAA2_FLOW_QOS_TYPE; 174256c1817dSJun Yang } 174356c1817dSJun Yang 1744200a33e4SJun Yang ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group, 174556c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 174656c1817dSJun Yang if (ret) { 1747200a33e4SJun Yang DPAA2_PMD_ERR("QoS faf rule set failed"); 174856c1817dSJun Yang return -EINVAL; 174956c1817dSJun Yang } 175056c1817dSJun Yang } 175156c1817dSJun Yang 175256c1817dSJun Yang if (dist_type & DPAA2_FLOW_FS_TYPE) { 175356c1817dSJun Yang extract = &priv->extract.tc_key_extract[group]; 175456c1817dSJun Yang key_profile = &extract->key_profile; 175556c1817dSJun Yang 175656c1817dSJun Yang index = dpaa2_flow_extract_search(key_profile, 1757200a33e4SJun Yang DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte); 175856c1817dSJun Yang if (index < 0) { 1759200a33e4SJun Yang ret = dpaa2_flow_faf_add_hdr(faf_byte, 1760200a33e4SJun Yang priv, DPAA2_FLOW_FS_TYPE, group, 176156c1817dSJun Yang NULL); 176256c1817dSJun Yang if (ret) { 1763200a33e4SJun Yang DPAA2_PMD_ERR("FS[%d] faf extract add failed", 176456c1817dSJun Yang group); 176556c1817dSJun Yang 176656c1817dSJun Yang return -EINVAL; 176756c1817dSJun Yang } 176856c1817dSJun Yang local_cfg |= DPAA2_FLOW_FS_TYPE; 176956c1817dSJun Yang } 177056c1817dSJun Yang 1771200a33e4SJun Yang ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group, 177256c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 177356c1817dSJun Yang if (ret) { 1774200a33e4SJun Yang DPAA2_PMD_ERR("FS[%d] faf rule set failed", 177556c1817dSJun Yang group); 177656c1817dSJun Yang return -EINVAL; 177756c1817dSJun Yang } 177856c1817dSJun Yang } 177956c1817dSJun Yang 178056c1817dSJun Yang if (recfg) 1781200a33e4SJun Yang *recfg |= local_cfg; 178256c1817dSJun Yang 178356c1817dSJun Yang return 0; 178456c1817dSJun Yang } 178556c1817dSJun Yang 178656c1817dSJun Yang static int 178739c8044fSJun Yang dpaa2_flow_add_pr_extract_rule(struct dpaa2_dev_flow *flow, 178839c8044fSJun Yang uint32_t pr_offset, uint32_t pr_size, 178939c8044fSJun Yang const void *key, const void *mask, 179039c8044fSJun Yang struct dpaa2_dev_priv *priv, int tc_id, int *recfg, 179139c8044fSJun Yang enum dpaa2_flow_dist_type dist_type) 179239c8044fSJun Yang { 179339c8044fSJun Yang int index, ret, local_cfg = 0; 179439c8044fSJun Yang struct dpaa2_key_extract *key_extract; 179539c8044fSJun Yang struct dpaa2_key_profile *key_profile; 179639c8044fSJun Yang uint32_t pr_field = pr_offset << 16 | pr_size; 179739c8044fSJun Yang 179839c8044fSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 179939c8044fSJun Yang key_extract = &priv->extract.qos_key_extract; 180039c8044fSJun Yang else 180139c8044fSJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 180239c8044fSJun Yang 180339c8044fSJun Yang key_profile = &key_extract->key_profile; 180439c8044fSJun Yang 180539c8044fSJun Yang index = dpaa2_flow_extract_search(key_profile, 180639c8044fSJun Yang DPAA2_PR_KEY, NET_PROT_NONE, pr_field); 180739c8044fSJun Yang if (index < 0) { 180839c8044fSJun Yang ret = dpaa2_flow_pr_add_hdr(pr_offset, 180939c8044fSJun Yang pr_size, priv, 181039c8044fSJun Yang dist_type, tc_id, NULL); 181139c8044fSJun Yang if (ret) { 181239c8044fSJun Yang DPAA2_PMD_ERR("PR add off(%d)/size(%d) failed", 181339c8044fSJun Yang pr_offset, pr_size); 181439c8044fSJun Yang 181539c8044fSJun Yang return ret; 181639c8044fSJun Yang } 181739c8044fSJun Yang local_cfg |= dist_type; 181839c8044fSJun Yang } 181939c8044fSJun Yang 182039c8044fSJun Yang ret = dpaa2_flow_pr_rule_data_set(flow, key_profile, 182139c8044fSJun Yang pr_offset, pr_size, key, mask, dist_type); 182239c8044fSJun Yang if (ret) { 182339c8044fSJun Yang DPAA2_PMD_ERR("PR off(%d)/size(%d) rule data set failed", 182439c8044fSJun Yang pr_offset, pr_size); 182539c8044fSJun Yang 182639c8044fSJun Yang return ret; 182739c8044fSJun Yang } 182839c8044fSJun Yang 182939c8044fSJun Yang if (recfg) 183039c8044fSJun Yang *recfg |= local_cfg; 183139c8044fSJun Yang 183239c8044fSJun Yang return 0; 183339c8044fSJun Yang } 183439c8044fSJun Yang 183539c8044fSJun Yang static int 183656c1817dSJun Yang dpaa2_flow_add_hdr_extract_rule(struct dpaa2_dev_flow *flow, 183756c1817dSJun Yang enum net_prot prot, uint32_t field, 183856c1817dSJun Yang const void *key, const void *mask, int size, 183956c1817dSJun Yang struct dpaa2_dev_priv *priv, int tc_id, int *recfg, 184056c1817dSJun Yang enum dpaa2_flow_dist_type dist_type) 184156c1817dSJun Yang { 184256c1817dSJun Yang int index, ret, local_cfg = 0; 184356c1817dSJun Yang struct dpaa2_key_extract *key_extract; 184456c1817dSJun Yang struct dpaa2_key_profile *key_profile; 184556c1817dSJun Yang 184656c1817dSJun Yang if (dpaa2_flow_ip_address_extract(prot, field)) 184756c1817dSJun Yang return -EINVAL; 184856c1817dSJun Yang 184956c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 185056c1817dSJun Yang key_extract = &priv->extract.qos_key_extract; 185156c1817dSJun Yang else 185256c1817dSJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 185356c1817dSJun Yang 185456c1817dSJun Yang key_profile = &key_extract->key_profile; 185556c1817dSJun Yang 185656c1817dSJun Yang index = dpaa2_flow_extract_search(key_profile, 1857200a33e4SJun Yang DPAA2_NET_PROT_KEY, prot, field); 185856c1817dSJun Yang if (index < 0) { 185956c1817dSJun Yang ret = dpaa2_flow_extract_add_hdr(prot, 186056c1817dSJun Yang field, size, priv, 186156c1817dSJun Yang dist_type, tc_id, NULL); 186256c1817dSJun Yang if (ret) { 186356c1817dSJun Yang DPAA2_PMD_ERR("QoS Extract P(%d)/F(%d) failed", 186456c1817dSJun Yang prot, field); 186556c1817dSJun Yang 186656c1817dSJun Yang return ret; 186756c1817dSJun Yang } 186856c1817dSJun Yang local_cfg |= dist_type; 186956c1817dSJun Yang } 187056c1817dSJun Yang 187156c1817dSJun Yang ret = dpaa2_flow_hdr_rule_data_set(flow, key_profile, 187256c1817dSJun Yang prot, field, size, key, mask, dist_type); 187356c1817dSJun Yang if (ret) { 187456c1817dSJun Yang DPAA2_PMD_ERR("QoS P(%d)/F(%d) rule data set failed", 187556c1817dSJun Yang prot, field); 187656c1817dSJun Yang 187756c1817dSJun Yang return ret; 187856c1817dSJun Yang } 187956c1817dSJun Yang 188056c1817dSJun Yang if (recfg) 188156c1817dSJun Yang *recfg |= local_cfg; 188256c1817dSJun Yang 188356c1817dSJun Yang return 0; 188456c1817dSJun Yang } 188556c1817dSJun Yang 188656c1817dSJun Yang static int 188756c1817dSJun Yang dpaa2_flow_add_ipaddr_extract_rule(struct dpaa2_dev_flow *flow, 188856c1817dSJun Yang enum net_prot prot, uint32_t field, 188956c1817dSJun Yang const void *key, const void *mask, int size, 189056c1817dSJun Yang struct dpaa2_dev_priv *priv, int tc_id, int *recfg, 189156c1817dSJun Yang enum dpaa2_flow_dist_type dist_type) 189256c1817dSJun Yang { 189356c1817dSJun Yang int local_cfg = 0, num, ipaddr_extract_len = 0; 189456c1817dSJun Yang struct dpaa2_key_extract *key_extract; 189556c1817dSJun Yang struct dpaa2_key_profile *key_profile; 189656c1817dSJun Yang struct dpkg_profile_cfg *dpkg; 189756c1817dSJun Yang uint8_t *key_addr, *mask_addr; 189856c1817dSJun Yang union ip_addr_extract_rule *ip_addr_data; 189956c1817dSJun Yang union ip_addr_extract_rule *ip_addr_mask; 190056c1817dSJun Yang enum net_prot orig_prot; 190156c1817dSJun Yang uint32_t orig_field; 190256c1817dSJun Yang 190356c1817dSJun Yang if (prot != NET_PROT_IPV4 && prot != NET_PROT_IPV6) 190456c1817dSJun Yang return -EINVAL; 190556c1817dSJun Yang 190656c1817dSJun Yang if (prot == NET_PROT_IPV4 && field != NH_FLD_IPV4_SRC_IP && 190756c1817dSJun Yang field != NH_FLD_IPV4_DST_IP) { 190856c1817dSJun Yang return -EINVAL; 190956c1817dSJun Yang } 191056c1817dSJun Yang 191156c1817dSJun Yang if (prot == NET_PROT_IPV6 && field != NH_FLD_IPV6_SRC_IP && 191256c1817dSJun Yang field != NH_FLD_IPV6_DST_IP) { 191356c1817dSJun Yang return -EINVAL; 191456c1817dSJun Yang } 191556c1817dSJun Yang 191656c1817dSJun Yang orig_prot = prot; 191756c1817dSJun Yang orig_field = field; 191856c1817dSJun Yang 191956c1817dSJun Yang if (prot == NET_PROT_IPV4 && 192056c1817dSJun Yang field == NH_FLD_IPV4_SRC_IP) { 192156c1817dSJun Yang prot = NET_PROT_IP; 192256c1817dSJun Yang field = NH_FLD_IP_SRC; 192356c1817dSJun Yang } else if (prot == NET_PROT_IPV4 && 192456c1817dSJun Yang field == NH_FLD_IPV4_DST_IP) { 192556c1817dSJun Yang prot = NET_PROT_IP; 192656c1817dSJun Yang field = NH_FLD_IP_DST; 192756c1817dSJun Yang } else if (prot == NET_PROT_IPV6 && 192856c1817dSJun Yang field == NH_FLD_IPV6_SRC_IP) { 192956c1817dSJun Yang prot = NET_PROT_IP; 193056c1817dSJun Yang field = NH_FLD_IP_SRC; 193156c1817dSJun Yang } else if (prot == NET_PROT_IPV6 && 193256c1817dSJun Yang field == NH_FLD_IPV6_DST_IP) { 193356c1817dSJun Yang prot = NET_PROT_IP; 193456c1817dSJun Yang field = NH_FLD_IP_DST; 193556c1817dSJun Yang } else { 193656c1817dSJun Yang DPAA2_PMD_ERR("Inval P(%d)/F(%d) to extract ip address", 193756c1817dSJun Yang prot, field); 193856c1817dSJun Yang return -EINVAL; 193956c1817dSJun Yang } 194056c1817dSJun Yang 194156c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 194256c1817dSJun Yang key_extract = &priv->extract.qos_key_extract; 194356c1817dSJun Yang key_profile = &key_extract->key_profile; 194456c1817dSJun Yang dpkg = &key_extract->dpkg; 194556c1817dSJun Yang num = key_profile->num; 194656c1817dSJun Yang key_addr = flow->qos_key_addr; 194756c1817dSJun Yang mask_addr = flow->qos_mask_addr; 194856c1817dSJun Yang } else { 194956c1817dSJun Yang key_extract = &priv->extract.tc_key_extract[tc_id]; 195056c1817dSJun Yang key_profile = &key_extract->key_profile; 195156c1817dSJun Yang dpkg = &key_extract->dpkg; 195256c1817dSJun Yang num = key_profile->num; 195356c1817dSJun Yang key_addr = flow->fs_key_addr; 195456c1817dSJun Yang mask_addr = flow->fs_mask_addr; 195556c1817dSJun Yang } 195656c1817dSJun Yang 195756c1817dSJun Yang if (num >= DPKG_MAX_NUM_OF_EXTRACTS) { 195856c1817dSJun Yang DPAA2_PMD_ERR("Number of extracts overflows"); 195956c1817dSJun Yang return -EINVAL; 196056c1817dSJun Yang } 196156c1817dSJun Yang 196256c1817dSJun Yang if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) { 196356c1817dSJun Yang if (field == NH_FLD_IP_SRC) 196456c1817dSJun Yang key_profile->ip_addr_type = IP_SRC_EXTRACT; 196556c1817dSJun Yang else 196656c1817dSJun Yang key_profile->ip_addr_type = IP_DST_EXTRACT; 196756c1817dSJun Yang ipaddr_extract_len = size; 196856c1817dSJun Yang 196956c1817dSJun Yang key_profile->ip_addr_extract_pos = num; 197056c1817dSJun Yang if (num > 0) { 197156c1817dSJun Yang key_profile->ip_addr_extract_off = 197256c1817dSJun Yang key_profile->key_offset[num - 1] + 197356c1817dSJun Yang key_profile->key_size[num - 1]; 197456c1817dSJun Yang } else { 197556c1817dSJun Yang key_profile->ip_addr_extract_off = 0; 197656c1817dSJun Yang } 197756c1817dSJun Yang key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE; 197856c1817dSJun Yang } else if (key_profile->ip_addr_type == IP_SRC_EXTRACT) { 197956c1817dSJun Yang if (field == NH_FLD_IP_SRC) { 198056c1817dSJun Yang ipaddr_extract_len = size; 198156c1817dSJun Yang goto rule_configure; 198256c1817dSJun Yang } 198356c1817dSJun Yang key_profile->ip_addr_type = IP_SRC_DST_EXTRACT; 198456c1817dSJun Yang ipaddr_extract_len = size * 2; 198556c1817dSJun Yang key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE; 198656c1817dSJun Yang } else if (key_profile->ip_addr_type == IP_DST_EXTRACT) { 198756c1817dSJun Yang if (field == NH_FLD_IP_DST) { 198856c1817dSJun Yang ipaddr_extract_len = size; 198956c1817dSJun Yang goto rule_configure; 199056c1817dSJun Yang } 199156c1817dSJun Yang key_profile->ip_addr_type = IP_DST_SRC_EXTRACT; 199256c1817dSJun Yang ipaddr_extract_len = size * 2; 199356c1817dSJun Yang key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE; 199456c1817dSJun Yang } 199556c1817dSJun Yang key_profile->num++; 1996200a33e4SJun Yang key_profile->prot_field[num].type = DPAA2_NET_PROT_KEY; 199756c1817dSJun Yang 199856c1817dSJun Yang dpkg->extracts[num].extract.from_hdr.prot = prot; 199956c1817dSJun Yang dpkg->extracts[num].extract.from_hdr.field = field; 200056c1817dSJun Yang dpkg->extracts[num].extract.from_hdr.type = DPKG_FULL_FIELD; 200156c1817dSJun Yang dpkg->num_extracts++; 200256c1817dSJun Yang 200356c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) 200456c1817dSJun Yang local_cfg = DPAA2_FLOW_QOS_TYPE; 200556c1817dSJun Yang else 200656c1817dSJun Yang local_cfg = DPAA2_FLOW_FS_TYPE; 200756c1817dSJun Yang 200856c1817dSJun Yang rule_configure: 200956c1817dSJun Yang key_addr += key_profile->ip_addr_extract_off; 201056c1817dSJun Yang ip_addr_data = (union ip_addr_extract_rule *)key_addr; 201156c1817dSJun Yang mask_addr += key_profile->ip_addr_extract_off; 201256c1817dSJun Yang ip_addr_mask = (union ip_addr_extract_rule *)mask_addr; 201356c1817dSJun Yang 201456c1817dSJun Yang if (orig_prot == NET_PROT_IPV4 && 201556c1817dSJun Yang orig_field == NH_FLD_IPV4_SRC_IP) { 201656c1817dSJun Yang if (key_profile->ip_addr_type == IP_SRC_EXTRACT || 201756c1817dSJun Yang key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) { 201856c1817dSJun Yang memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_src, 201956c1817dSJun Yang key, size); 202056c1817dSJun Yang memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_src, 202156c1817dSJun Yang mask, size); 202256c1817dSJun Yang } else { 202356c1817dSJun Yang memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_src, 202456c1817dSJun Yang key, size); 202556c1817dSJun Yang memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_src, 202656c1817dSJun Yang mask, size); 202756c1817dSJun Yang } 202856c1817dSJun Yang } else if (orig_prot == NET_PROT_IPV4 && 202956c1817dSJun Yang orig_field == NH_FLD_IPV4_DST_IP) { 203056c1817dSJun Yang if (key_profile->ip_addr_type == IP_DST_EXTRACT || 203156c1817dSJun Yang key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) { 203256c1817dSJun Yang memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_dst, 203356c1817dSJun Yang key, size); 203456c1817dSJun Yang memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_dst, 203556c1817dSJun Yang mask, size); 203656c1817dSJun Yang } else { 203756c1817dSJun Yang memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_dst, 203856c1817dSJun Yang key, size); 203956c1817dSJun Yang memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_dst, 204056c1817dSJun Yang mask, size); 204156c1817dSJun Yang } 204256c1817dSJun Yang } else if (orig_prot == NET_PROT_IPV6 && 204356c1817dSJun Yang orig_field == NH_FLD_IPV6_SRC_IP) { 204456c1817dSJun Yang if (key_profile->ip_addr_type == IP_SRC_EXTRACT || 204556c1817dSJun Yang key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) { 204656c1817dSJun Yang memcpy(ip_addr_data->ipv6_sd_addr.ipv6_src, 204756c1817dSJun Yang key, size); 204856c1817dSJun Yang memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_src, 204956c1817dSJun Yang mask, size); 205056c1817dSJun Yang } else { 205156c1817dSJun Yang memcpy(ip_addr_data->ipv6_ds_addr.ipv6_src, 205256c1817dSJun Yang key, size); 205356c1817dSJun Yang memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_src, 205456c1817dSJun Yang mask, size); 205556c1817dSJun Yang } 205656c1817dSJun Yang } else if (orig_prot == NET_PROT_IPV6 && 205756c1817dSJun Yang orig_field == NH_FLD_IPV6_DST_IP) { 205856c1817dSJun Yang if (key_profile->ip_addr_type == IP_DST_EXTRACT || 205956c1817dSJun Yang key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) { 206056c1817dSJun Yang memcpy(ip_addr_data->ipv6_ds_addr.ipv6_dst, 206156c1817dSJun Yang key, size); 206256c1817dSJun Yang memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_dst, 206356c1817dSJun Yang mask, size); 206456c1817dSJun Yang } else { 206556c1817dSJun Yang memcpy(ip_addr_data->ipv6_sd_addr.ipv6_dst, 206656c1817dSJun Yang key, size); 206756c1817dSJun Yang memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_dst, 206856c1817dSJun Yang mask, size); 206956c1817dSJun Yang } 207056c1817dSJun Yang } 207156c1817dSJun Yang 207256c1817dSJun Yang if (dist_type == DPAA2_FLOW_QOS_TYPE) { 207356c1817dSJun Yang flow->qos_rule_size = 207456c1817dSJun Yang key_profile->ip_addr_extract_off + ipaddr_extract_len; 207556c1817dSJun Yang } else { 207656c1817dSJun Yang flow->fs_rule_size = 207756c1817dSJun Yang key_profile->ip_addr_extract_off + ipaddr_extract_len; 207856c1817dSJun Yang } 207956c1817dSJun Yang 208056c1817dSJun Yang if (recfg) 208156c1817dSJun Yang *recfg |= local_cfg; 208256c1817dSJun Yang 208356c1817dSJun Yang return 0; 208456c1817dSJun Yang } 208556c1817dSJun Yang 208656c1817dSJun Yang static int 20879ec29343SJun Yang dpaa2_configure_flow_tunnel_eth(struct dpaa2_dev_flow *flow, 2088fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 2089fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 2090fe2b986aSSunil Kumar Kori const struct rte_flow_item *pattern, 20919ec29343SJun Yang int *device_configured) 20929ec29343SJun Yang { 20939ec29343SJun Yang int ret, local_cfg = 0; 20949ec29343SJun Yang uint32_t group; 20959ec29343SJun Yang const struct rte_flow_item_eth *spec, *mask; 20969ec29343SJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 20979ec29343SJun Yang const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0}; 20989ec29343SJun Yang 20999ec29343SJun Yang group = attr->group; 21009ec29343SJun Yang 21019ec29343SJun Yang /* Parse pattern list to get the matching parameters */ 21029ec29343SJun Yang spec = pattern->spec; 21039ec29343SJun Yang mask = pattern->mask ? 21049ec29343SJun Yang pattern->mask : &dpaa2_flow_item_eth_mask; 21059ec29343SJun Yang 21069ec29343SJun Yang /* Get traffic class index and flow id to be configured */ 21079ec29343SJun Yang flow->tc_id = group; 21089ec29343SJun Yang flow->tc_index = attr->priority; 21099ec29343SJun Yang 21109ec29343SJun Yang if (!spec) 21119ec29343SJun Yang return 0; 21129ec29343SJun Yang 21134cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 21144cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ETH); 21154cc5cf4aSJun Yang if (ret) { 21169ec29343SJun Yang DPAA2_PMD_WARN("Extract field(s) of ethernet failed"); 21179ec29343SJun Yang 21184cc5cf4aSJun Yang return ret; 21199ec29343SJun Yang } 21209ec29343SJun Yang 21219ec29343SJun Yang if (memcmp((const char *)&mask->src, 21229ec29343SJun Yang zero_cmp, RTE_ETHER_ADDR_LEN)) { 21239ec29343SJun Yang /*SRC[0:1]*/ 21249ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21259ec29343SJun Yang DPAA2_VXLAN_IN_SADDR0_OFFSET, 21269ec29343SJun Yang 1, &spec->src.addr_bytes[0], 21279ec29343SJun Yang &mask->src.addr_bytes[0], 21289ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 21299ec29343SJun Yang if (ret) 21309ec29343SJun Yang return ret; 21319ec29343SJun Yang /*SRC[1:2]*/ 21329ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21339ec29343SJun Yang DPAA2_VXLAN_IN_SADDR1_OFFSET, 21349ec29343SJun Yang 2, &spec->src.addr_bytes[1], 21359ec29343SJun Yang &mask->src.addr_bytes[1], 21369ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 21379ec29343SJun Yang if (ret) 21389ec29343SJun Yang return ret; 21399ec29343SJun Yang /*SRC[3:1]*/ 21409ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21419ec29343SJun Yang DPAA2_VXLAN_IN_SADDR3_OFFSET, 21429ec29343SJun Yang 1, &spec->src.addr_bytes[3], 21439ec29343SJun Yang &mask->src.addr_bytes[3], 21449ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 21459ec29343SJun Yang if (ret) 21469ec29343SJun Yang return ret; 21479ec29343SJun Yang /*SRC[4:2]*/ 21489ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21499ec29343SJun Yang DPAA2_VXLAN_IN_SADDR4_OFFSET, 21509ec29343SJun Yang 2, &spec->src.addr_bytes[4], 21519ec29343SJun Yang &mask->src.addr_bytes[4], 21529ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 21539ec29343SJun Yang if (ret) 21549ec29343SJun Yang return ret; 21559ec29343SJun Yang 21569ec29343SJun Yang /*SRC[0:1]*/ 21579ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21589ec29343SJun Yang DPAA2_VXLAN_IN_SADDR0_OFFSET, 21599ec29343SJun Yang 1, &spec->src.addr_bytes[0], 21609ec29343SJun Yang &mask->src.addr_bytes[0], 21619ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 21629ec29343SJun Yang if (ret) 21639ec29343SJun Yang return ret; 21649ec29343SJun Yang /*SRC[1:2]*/ 21659ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21669ec29343SJun Yang DPAA2_VXLAN_IN_SADDR1_OFFSET, 21679ec29343SJun Yang 2, &spec->src.addr_bytes[1], 21689ec29343SJun Yang &mask->src.addr_bytes[1], 21699ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 21709ec29343SJun Yang if (ret) 21719ec29343SJun Yang return ret; 21729ec29343SJun Yang /*SRC[3:1]*/ 21739ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21749ec29343SJun Yang DPAA2_VXLAN_IN_SADDR3_OFFSET, 21759ec29343SJun Yang 1, &spec->src.addr_bytes[3], 21769ec29343SJun Yang &mask->src.addr_bytes[3], 21779ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 21789ec29343SJun Yang if (ret) 21799ec29343SJun Yang return ret; 21809ec29343SJun Yang /*SRC[4:2]*/ 21819ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21829ec29343SJun Yang DPAA2_VXLAN_IN_SADDR4_OFFSET, 21839ec29343SJun Yang 2, &spec->src.addr_bytes[4], 21849ec29343SJun Yang &mask->src.addr_bytes[4], 21859ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 21869ec29343SJun Yang if (ret) 21879ec29343SJun Yang return ret; 21889ec29343SJun Yang } 21899ec29343SJun Yang 21909ec29343SJun Yang if (memcmp((const char *)&mask->dst, 21919ec29343SJun Yang zero_cmp, RTE_ETHER_ADDR_LEN)) { 21929ec29343SJun Yang /*DST[0:1]*/ 21939ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 21949ec29343SJun Yang DPAA2_VXLAN_IN_DADDR0_OFFSET, 21959ec29343SJun Yang 1, &spec->dst.addr_bytes[0], 21969ec29343SJun Yang &mask->dst.addr_bytes[0], 21979ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 21989ec29343SJun Yang if (ret) 21999ec29343SJun Yang return ret; 22009ec29343SJun Yang /*DST[1:1]*/ 22019ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22029ec29343SJun Yang DPAA2_VXLAN_IN_DADDR1_OFFSET, 22039ec29343SJun Yang 1, &spec->dst.addr_bytes[1], 22049ec29343SJun Yang &mask->dst.addr_bytes[1], 22059ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 22069ec29343SJun Yang if (ret) 22079ec29343SJun Yang return ret; 22089ec29343SJun Yang /*DST[2:3]*/ 22099ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22109ec29343SJun Yang DPAA2_VXLAN_IN_DADDR2_OFFSET, 22119ec29343SJun Yang 3, &spec->dst.addr_bytes[2], 22129ec29343SJun Yang &mask->dst.addr_bytes[2], 22139ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 22149ec29343SJun Yang if (ret) 22159ec29343SJun Yang return ret; 22169ec29343SJun Yang /*DST[5:1]*/ 22179ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22189ec29343SJun Yang DPAA2_VXLAN_IN_DADDR5_OFFSET, 22199ec29343SJun Yang 1, &spec->dst.addr_bytes[5], 22209ec29343SJun Yang &mask->dst.addr_bytes[5], 22219ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 22229ec29343SJun Yang if (ret) 22239ec29343SJun Yang return ret; 22249ec29343SJun Yang 22259ec29343SJun Yang /*DST[0:1]*/ 22269ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22279ec29343SJun Yang DPAA2_VXLAN_IN_DADDR0_OFFSET, 22289ec29343SJun Yang 1, &spec->dst.addr_bytes[0], 22299ec29343SJun Yang &mask->dst.addr_bytes[0], 22309ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 22319ec29343SJun Yang if (ret) 22329ec29343SJun Yang return ret; 22339ec29343SJun Yang /*DST[1:1]*/ 22349ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22359ec29343SJun Yang DPAA2_VXLAN_IN_DADDR1_OFFSET, 22369ec29343SJun Yang 1, &spec->dst.addr_bytes[1], 22379ec29343SJun Yang &mask->dst.addr_bytes[1], 22389ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 22399ec29343SJun Yang if (ret) 22409ec29343SJun Yang return ret; 22419ec29343SJun Yang /*DST[2:3]*/ 22429ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22439ec29343SJun Yang DPAA2_VXLAN_IN_DADDR2_OFFSET, 22449ec29343SJun Yang 3, &spec->dst.addr_bytes[2], 22459ec29343SJun Yang &mask->dst.addr_bytes[2], 22469ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 22479ec29343SJun Yang if (ret) 22489ec29343SJun Yang return ret; 22499ec29343SJun Yang /*DST[5:1]*/ 22509ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22519ec29343SJun Yang DPAA2_VXLAN_IN_DADDR5_OFFSET, 22529ec29343SJun Yang 1, &spec->dst.addr_bytes[5], 22539ec29343SJun Yang &mask->dst.addr_bytes[5], 22549ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 22559ec29343SJun Yang if (ret) 22569ec29343SJun Yang return ret; 22579ec29343SJun Yang } 22589ec29343SJun Yang 22599ec29343SJun Yang if (memcmp((const char *)&mask->type, 22609ec29343SJun Yang zero_cmp, sizeof(rte_be16_t))) { 22619ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22629ec29343SJun Yang DPAA2_VXLAN_IN_TYPE_OFFSET, 22639ec29343SJun Yang sizeof(rte_be16_t), &spec->type, &mask->type, 22649ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 22659ec29343SJun Yang if (ret) 22669ec29343SJun Yang return ret; 22679ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 22689ec29343SJun Yang DPAA2_VXLAN_IN_TYPE_OFFSET, 22699ec29343SJun Yang sizeof(rte_be16_t), &spec->type, &mask->type, 22709ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 22719ec29343SJun Yang if (ret) 22729ec29343SJun Yang return ret; 22739ec29343SJun Yang } 22749ec29343SJun Yang 22759ec29343SJun Yang (*device_configured) |= local_cfg; 22769ec29343SJun Yang 22779ec29343SJun Yang return 0; 22789ec29343SJun Yang } 22799ec29343SJun Yang 22809ec29343SJun Yang static int 22819ec29343SJun Yang dpaa2_configure_flow_eth(struct dpaa2_dev_flow *flow, 22829ec29343SJun Yang struct rte_eth_dev *dev, 22839ec29343SJun Yang const struct rte_flow_attr *attr, 22849ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 2285fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 22865f176728SJun Yang struct rte_flow_error *error __rte_unused, 22875f176728SJun Yang int *device_configured) 2288fe2b986aSSunil Kumar Kori { 228956c1817dSJun Yang int ret, local_cfg = 0; 2290fe2b986aSSunil Kumar Kori uint32_t group; 2291fe2b986aSSunil Kumar Kori const struct rte_flow_item_eth *spec, *mask; 2292fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 22935f176728SJun Yang const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0}; 22949ec29343SJun Yang const struct rte_flow_item *pattern = 22959ec29343SJun Yang &dpaa2_pattern->generic_item; 22969ec29343SJun Yang 22979ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 22989ec29343SJun Yang return dpaa2_configure_flow_tunnel_eth(flow, 22999ec29343SJun Yang dev, attr, pattern, device_configured); 23009ec29343SJun Yang } 2301fe2b986aSSunil Kumar Kori 2302fe2b986aSSunil Kumar Kori group = attr->group; 2303fe2b986aSSunil Kumar Kori 2304fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 230556c1817dSJun Yang spec = pattern->spec; 230656c1817dSJun Yang mask = pattern->mask ? 230756c1817dSJun Yang pattern->mask : &dpaa2_flow_item_eth_mask; 2308fe2b986aSSunil Kumar Kori 23095f176728SJun Yang /* Get traffic class index and flow id to be configured */ 23105f176728SJun Yang flow->tc_id = group; 23115f176728SJun Yang flow->tc_index = attr->priority; 23125f176728SJun Yang 2313200a33e4SJun Yang if (!spec) { 2314200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2315200a33e4SJun Yang FAF_ETH_FRAM, DPAA2_FLOW_QOS_TYPE, 2316200a33e4SJun Yang group, &local_cfg); 2317200a33e4SJun Yang if (ret) 2318200a33e4SJun Yang return ret; 2319200a33e4SJun Yang 2320200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2321200a33e4SJun Yang FAF_ETH_FRAM, DPAA2_FLOW_FS_TYPE, 2322200a33e4SJun Yang group, &local_cfg); 2323200a33e4SJun Yang if (ret) 2324200a33e4SJun Yang return ret; 2325200a33e4SJun Yang 2326200a33e4SJun Yang (*device_configured) |= local_cfg; 2327200a33e4SJun Yang return 0; 2328200a33e4SJun Yang } 2329200a33e4SJun Yang 23304cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 23314cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ETH); 23324cc5cf4aSJun Yang if (ret) { 233356c1817dSJun Yang DPAA2_PMD_WARN("Extract field(s) of ethernet failed"); 2334926c1279SJun Yang 23354cc5cf4aSJun Yang return ret; 2336926c1279SJun Yang } 2337926c1279SJun Yang 233856c1817dSJun Yang if (memcmp((const char *)&mask->src, 233956c1817dSJun Yang zero_cmp, RTE_ETHER_ADDR_LEN)) { 234056c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 234156c1817dSJun Yang NH_FLD_ETH_SA, &spec->src.addr_bytes, 234256c1817dSJun Yang &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN, 234356c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 234456c1817dSJun Yang if (ret) 234556c1817dSJun Yang return ret; 23465f176728SJun Yang 234756c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 234856c1817dSJun Yang NH_FLD_ETH_SA, &spec->src.addr_bytes, 234956c1817dSJun Yang &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN, 235056c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 235156c1817dSJun Yang if (ret) 235256c1817dSJun Yang return ret; 23535f176728SJun Yang } 23545f176728SJun Yang 235556c1817dSJun Yang if (memcmp((const char *)&mask->dst, 235656c1817dSJun Yang zero_cmp, RTE_ETHER_ADDR_LEN)) { 235756c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 235856c1817dSJun Yang NH_FLD_ETH_DA, &spec->dst.addr_bytes, 235956c1817dSJun Yang &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN, 236056c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 236156c1817dSJun Yang if (ret) 236256c1817dSJun Yang return ret; 236356c1817dSJun Yang 236456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 236556c1817dSJun Yang NH_FLD_ETH_DA, &spec->dst.addr_bytes, 236656c1817dSJun Yang &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN, 236756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 236856c1817dSJun Yang if (ret) 236956c1817dSJun Yang return ret; 23705f176728SJun Yang } 23715f176728SJun Yang 237256c1817dSJun Yang if (memcmp((const char *)&mask->type, 237356c1817dSJun Yang zero_cmp, sizeof(rte_be16_t))) { 237456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 237556c1817dSJun Yang NH_FLD_ETH_TYPE, &spec->type, 237656c1817dSJun Yang &mask->type, sizeof(rte_be16_t), 237756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 237856c1817dSJun Yang if (ret) 237956c1817dSJun Yang return ret; 23805f176728SJun Yang 238156c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH, 238256c1817dSJun Yang NH_FLD_ETH_TYPE, &spec->type, 238356c1817dSJun Yang &mask->type, sizeof(rte_be16_t), 238456c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 238556c1817dSJun Yang if (ret) 238656c1817dSJun Yang return ret; 23875f176728SJun Yang } 2388fe2b986aSSunil Kumar Kori 23895f176728SJun Yang (*device_configured) |= local_cfg; 23904e445633SJun Yang 23915f176728SJun Yang return 0; 2392fe2b986aSSunil Kumar Kori } 2393fe2b986aSSunil Kumar Kori 2394fe2b986aSSunil Kumar Kori static int 23959ec29343SJun Yang dpaa2_configure_flow_tunnel_vlan(struct dpaa2_dev_flow *flow, 2396fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 2397fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 2398fe2b986aSSunil Kumar Kori const struct rte_flow_item *pattern, 23999ec29343SJun Yang int *device_configured) 24009ec29343SJun Yang { 24019ec29343SJun Yang int ret, local_cfg = 0; 24029ec29343SJun Yang uint32_t group; 24039ec29343SJun Yang const struct rte_flow_item_vlan *spec, *mask; 24049ec29343SJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 24059ec29343SJun Yang 24069ec29343SJun Yang group = attr->group; 24079ec29343SJun Yang 24089ec29343SJun Yang /* Parse pattern list to get the matching parameters */ 24099ec29343SJun Yang spec = pattern->spec; 24109ec29343SJun Yang mask = pattern->mask ? 24119ec29343SJun Yang pattern->mask : &dpaa2_flow_item_vlan_mask; 24129ec29343SJun Yang 24139ec29343SJun Yang /* Get traffic class index and flow id to be configured */ 24149ec29343SJun Yang flow->tc_id = group; 24159ec29343SJun Yang flow->tc_index = attr->priority; 24169ec29343SJun Yang 24179ec29343SJun Yang if (!spec) { 24189ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 24199ec29343SJun Yang FAFE_VXLAN_IN_VLAN_FRAM, 24209ec29343SJun Yang DPAA2_FLOW_QOS_TYPE, 24219ec29343SJun Yang group, &local_cfg); 24229ec29343SJun Yang if (ret) 24239ec29343SJun Yang return ret; 24249ec29343SJun Yang 24259ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 24269ec29343SJun Yang FAFE_VXLAN_IN_VLAN_FRAM, 24279ec29343SJun Yang DPAA2_FLOW_FS_TYPE, 24289ec29343SJun Yang group, &local_cfg); 24299ec29343SJun Yang if (ret) 24309ec29343SJun Yang return ret; 24319ec29343SJun Yang 24329ec29343SJun Yang (*device_configured) |= local_cfg; 24339ec29343SJun Yang return 0; 24349ec29343SJun Yang } 24359ec29343SJun Yang 24364cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 24374cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_VLAN); 24384cc5cf4aSJun Yang if (ret) { 24399ec29343SJun Yang DPAA2_PMD_WARN("Extract field(s) of vlan not support."); 24409ec29343SJun Yang 24414cc5cf4aSJun Yang return ret; 24429ec29343SJun Yang } 24439ec29343SJun Yang 24449ec29343SJun Yang if (!mask->tci) 24459ec29343SJun Yang return 0; 24469ec29343SJun Yang 24479ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 24489ec29343SJun Yang DPAA2_VXLAN_IN_TCI_OFFSET, 24499ec29343SJun Yang sizeof(rte_be16_t), &spec->tci, &mask->tci, 24509ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 24519ec29343SJun Yang if (ret) 24529ec29343SJun Yang return ret; 24539ec29343SJun Yang 24549ec29343SJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 24559ec29343SJun Yang DPAA2_VXLAN_IN_TCI_OFFSET, 24569ec29343SJun Yang sizeof(rte_be16_t), &spec->tci, &mask->tci, 24579ec29343SJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 24589ec29343SJun Yang if (ret) 24599ec29343SJun Yang return ret; 24609ec29343SJun Yang 24619ec29343SJun Yang (*device_configured) |= local_cfg; 24629ec29343SJun Yang 24639ec29343SJun Yang return 0; 24649ec29343SJun Yang } 24659ec29343SJun Yang 24669ec29343SJun Yang static int 24679ec29343SJun Yang dpaa2_configure_flow_vlan(struct dpaa2_dev_flow *flow, 24689ec29343SJun Yang struct rte_eth_dev *dev, 24699ec29343SJun Yang const struct rte_flow_attr *attr, 24709ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 2471fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 24725f176728SJun Yang struct rte_flow_error *error __rte_unused, 24735f176728SJun Yang int *device_configured) 2474fe2b986aSSunil Kumar Kori { 247556c1817dSJun Yang int ret, local_cfg = 0; 2476fe2b986aSSunil Kumar Kori uint32_t group; 2477fe2b986aSSunil Kumar Kori const struct rte_flow_item_vlan *spec, *mask; 2478fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 24799ec29343SJun Yang const struct rte_flow_item *pattern = 24809ec29343SJun Yang &dpaa2_pattern->generic_item; 24819ec29343SJun Yang 24829ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 24839ec29343SJun Yang return dpaa2_configure_flow_tunnel_vlan(flow, 24849ec29343SJun Yang dev, attr, pattern, device_configured); 24859ec29343SJun Yang } 2486fe2b986aSSunil Kumar Kori 2487fe2b986aSSunil Kumar Kori group = attr->group; 2488fe2b986aSSunil Kumar Kori 2489fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 249056c1817dSJun Yang spec = pattern->spec; 249156c1817dSJun Yang mask = pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask; 2492fe2b986aSSunil Kumar Kori 24935f176728SJun Yang /* Get traffic class index and flow id to be configured */ 24945f176728SJun Yang flow->tc_id = group; 24955f176728SJun Yang flow->tc_index = attr->priority; 2496fe2b986aSSunil Kumar Kori 24975f176728SJun Yang if (!spec) { 2498200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM, 2499200a33e4SJun Yang DPAA2_FLOW_QOS_TYPE, group, 2500200a33e4SJun Yang &local_cfg); 250156c1817dSJun Yang if (ret) 250256c1817dSJun Yang return ret; 2503200a33e4SJun Yang 2504200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM, 2505200a33e4SJun Yang DPAA2_FLOW_FS_TYPE, group, 2506200a33e4SJun Yang &local_cfg); 2507200a33e4SJun Yang if (ret) 2508200a33e4SJun Yang return ret; 2509200a33e4SJun Yang 25105f176728SJun Yang (*device_configured) |= local_cfg; 25115f176728SJun Yang return 0; 25125f176728SJun Yang } 25135f176728SJun Yang 25144cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 25154cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_VLAN); 25164cc5cf4aSJun Yang if (ret) { 2517926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of vlan not support."); 25184cc5cf4aSJun Yang return ret; 2519926c1279SJun Yang } 2520926c1279SJun Yang 252156c1817dSJun Yang if (!mask->tci) 25225f176728SJun Yang return 0; 25235f176728SJun Yang 252456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN, 252556c1817dSJun Yang NH_FLD_VLAN_TCI, &spec->tci, 252656c1817dSJun Yang &mask->tci, sizeof(rte_be16_t), 252756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 252856c1817dSJun Yang if (ret) 252956c1817dSJun Yang return ret; 25305f176728SJun Yang 253156c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN, 253256c1817dSJun Yang NH_FLD_VLAN_TCI, &spec->tci, 253356c1817dSJun Yang &mask->tci, sizeof(rte_be16_t), 253456c1817dSJun Yang priv, group, &local_cfg, 253556c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 253656c1817dSJun Yang if (ret) 253756c1817dSJun Yang return ret; 25385f176728SJun Yang 25395f176728SJun Yang (*device_configured) |= local_cfg; 25405f176728SJun Yang return 0; 2541fe2b986aSSunil Kumar Kori } 2542fe2b986aSSunil Kumar Kori 2543fe2b986aSSunil Kumar Kori static int 25444cc5cf4aSJun Yang dpaa2_configure_flow_ipv4(struct dpaa2_dev_flow *flow, 25454cc5cf4aSJun Yang struct rte_eth_dev *dev, 2546fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 25479ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 2548fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 25495f176728SJun Yang struct rte_flow_error *error __rte_unused, 25505f176728SJun Yang int *device_configured) 2551fe2b986aSSunil Kumar Kori { 255256c1817dSJun Yang int ret, local_cfg = 0; 2553fe2b986aSSunil Kumar Kori uint32_t group; 255456c1817dSJun Yang const struct rte_flow_item_ipv4 *spec_ipv4 = 0, *mask_ipv4 = 0; 25555f176728SJun Yang const void *key, *mask; 2556fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 25575f176728SJun Yang int size; 25589ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 2559fe2b986aSSunil Kumar Kori 2560fe2b986aSSunil Kumar Kori group = attr->group; 2561fe2b986aSSunil Kumar Kori 25625f176728SJun Yang /* Parse pattern list to get the matching parameters */ 256356c1817dSJun Yang spec_ipv4 = pattern->spec; 256456c1817dSJun Yang mask_ipv4 = pattern->mask ? 256556c1817dSJun Yang pattern->mask : &dpaa2_flow_item_ipv4_mask; 2566fe2b986aSSunil Kumar Kori 25679ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 25689ec29343SJun Yang if (spec_ipv4) { 25699ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-IPv4 distribution not support"); 25709ec29343SJun Yang return -ENOTSUP; 25719ec29343SJun Yang } 25729ec29343SJun Yang 25739ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 25749ec29343SJun Yang FAFE_VXLAN_IN_IPV4_FRAM, 25759ec29343SJun Yang DPAA2_FLOW_QOS_TYPE, group, 25769ec29343SJun Yang &local_cfg); 25779ec29343SJun Yang if (ret) 25789ec29343SJun Yang return ret; 25799ec29343SJun Yang 25809ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 25819ec29343SJun Yang FAFE_VXLAN_IN_IPV4_FRAM, 25829ec29343SJun Yang DPAA2_FLOW_FS_TYPE, group, 25839ec29343SJun Yang &local_cfg); 25849ec29343SJun Yang return ret; 25859ec29343SJun Yang } 25869ec29343SJun Yang 2587fe2b986aSSunil Kumar Kori /* Get traffic class index and flow id to be configured */ 2588fe2b986aSSunil Kumar Kori flow->tc_id = group; 25895f176728SJun Yang flow->tc_index = attr->priority; 2590fe2b986aSSunil Kumar Kori 2591200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM, 2592200a33e4SJun Yang DPAA2_FLOW_QOS_TYPE, group, 259356c1817dSJun Yang &local_cfg); 2594200a33e4SJun Yang if (ret) 259556c1817dSJun Yang return ret; 2596fe2b986aSSunil Kumar Kori 2597200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM, 2598200a33e4SJun Yang DPAA2_FLOW_FS_TYPE, group, &local_cfg); 2599200a33e4SJun Yang if (ret) 2600200a33e4SJun Yang return ret; 2601200a33e4SJun Yang 2602200a33e4SJun Yang if (!spec_ipv4) { 2603200a33e4SJun Yang (*device_configured) |= local_cfg; 26045f176728SJun Yang return 0; 2605200a33e4SJun Yang } 2606fe2b986aSSunil Kumar Kori 26074cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv4, 26084cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_IPV4); 26094cc5cf4aSJun Yang if (ret) { 2610926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of IPv4 not support."); 26114cc5cf4aSJun Yang return ret; 2612926c1279SJun Yang } 2613926c1279SJun Yang 261456c1817dSJun Yang if (mask_ipv4->hdr.src_addr) { 26155f176728SJun Yang key = &spec_ipv4->hdr.src_addr; 26165f176728SJun Yang mask = &mask_ipv4->hdr.src_addr; 261756c1817dSJun Yang size = sizeof(rte_be32_t); 261856c1817dSJun Yang 261956c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4, 262056c1817dSJun Yang NH_FLD_IPV4_SRC_IP, 262156c1817dSJun Yang key, mask, size, priv, 262256c1817dSJun Yang group, &local_cfg, 262356c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 262456c1817dSJun Yang if (ret) 262556c1817dSJun Yang return ret; 262656c1817dSJun Yang 262756c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4, 262856c1817dSJun Yang NH_FLD_IPV4_SRC_IP, 262956c1817dSJun Yang key, mask, size, priv, 263056c1817dSJun Yang group, &local_cfg, 263156c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 263256c1817dSJun Yang if (ret) 263356c1817dSJun Yang return ret; 2634fe2b986aSSunil Kumar Kori } 2635fe2b986aSSunil Kumar Kori 263656c1817dSJun Yang if (mask_ipv4->hdr.dst_addr) { 26375f176728SJun Yang key = &spec_ipv4->hdr.dst_addr; 26385f176728SJun Yang mask = &mask_ipv4->hdr.dst_addr; 263956c1817dSJun Yang size = sizeof(rte_be32_t); 264056c1817dSJun Yang 264156c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4, 264256c1817dSJun Yang NH_FLD_IPV4_DST_IP, 264356c1817dSJun Yang key, mask, size, priv, 264456c1817dSJun Yang group, &local_cfg, 264556c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 264656c1817dSJun Yang if (ret) 264756c1817dSJun Yang return ret; 264856c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4, 264956c1817dSJun Yang NH_FLD_IPV4_DST_IP, 265056c1817dSJun Yang key, mask, size, priv, 265156c1817dSJun Yang group, &local_cfg, 265256c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 265356c1817dSJun Yang if (ret) 265456c1817dSJun Yang return ret; 26555f176728SJun Yang } 26565f176728SJun Yang 265756c1817dSJun Yang if (mask_ipv4->hdr.next_proto_id) { 26585f176728SJun Yang key = &spec_ipv4->hdr.next_proto_id; 26595f176728SJun Yang mask = &mask_ipv4->hdr.next_proto_id; 266056c1817dSJun Yang size = sizeof(uint8_t); 26615f176728SJun Yang 266256c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP, 266356c1817dSJun Yang NH_FLD_IP_PROTO, key, 266456c1817dSJun Yang mask, size, priv, group, 266556c1817dSJun Yang &local_cfg, 266656c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 266756c1817dSJun Yang if (ret) 266856c1817dSJun Yang return ret; 26695f176728SJun Yang 267056c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP, 267156c1817dSJun Yang NH_FLD_IP_PROTO, key, 267256c1817dSJun Yang mask, size, priv, group, 267356c1817dSJun Yang &local_cfg, 267456c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 267556c1817dSJun Yang if (ret) 267656c1817dSJun Yang return ret; 2677fe2b986aSSunil Kumar Kori } 2678fe2b986aSSunil Kumar Kori 26795f176728SJun Yang (*device_configured) |= local_cfg; 26805f176728SJun Yang return 0; 2681fe2b986aSSunil Kumar Kori } 2682fe2b986aSSunil Kumar Kori 2683fe2b986aSSunil Kumar Kori static int 26844cc5cf4aSJun Yang dpaa2_configure_flow_ipv6(struct dpaa2_dev_flow *flow, 26854cc5cf4aSJun Yang struct rte_eth_dev *dev, 268656c1817dSJun Yang const struct rte_flow_attr *attr, 26879ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 268856c1817dSJun Yang const struct rte_flow_action actions[] __rte_unused, 268956c1817dSJun Yang struct rte_flow_error *error __rte_unused, 269056c1817dSJun Yang int *device_configured) 269156c1817dSJun Yang { 269256c1817dSJun Yang int ret, local_cfg = 0; 269356c1817dSJun Yang uint32_t group; 269456c1817dSJun Yang const struct rte_flow_item_ipv6 *spec_ipv6 = 0, *mask_ipv6 = 0; 269556c1817dSJun Yang const void *key, *mask; 269656c1817dSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 269756c1817dSJun Yang const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0}; 269856c1817dSJun Yang int size; 26999ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 270056c1817dSJun Yang 270156c1817dSJun Yang group = attr->group; 270256c1817dSJun Yang 270356c1817dSJun Yang /* Parse pattern list to get the matching parameters */ 270456c1817dSJun Yang spec_ipv6 = pattern->spec; 270556c1817dSJun Yang mask_ipv6 = pattern->mask ? pattern->mask : &dpaa2_flow_item_ipv6_mask; 270656c1817dSJun Yang 270756c1817dSJun Yang /* Get traffic class index and flow id to be configured */ 270856c1817dSJun Yang flow->tc_id = group; 270956c1817dSJun Yang flow->tc_index = attr->priority; 271056c1817dSJun Yang 27119ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 27129ec29343SJun Yang if (spec_ipv6) { 27139ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-IPv6 distribution not support"); 27149ec29343SJun Yang return -ENOTSUP; 27159ec29343SJun Yang } 27169ec29343SJun Yang 27179ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 27189ec29343SJun Yang FAFE_VXLAN_IN_IPV6_FRAM, 27199ec29343SJun Yang DPAA2_FLOW_QOS_TYPE, group, 27209ec29343SJun Yang &local_cfg); 27219ec29343SJun Yang if (ret) 27229ec29343SJun Yang return ret; 27239ec29343SJun Yang 27249ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 27259ec29343SJun Yang FAFE_VXLAN_IN_IPV6_FRAM, 27269ec29343SJun Yang DPAA2_FLOW_FS_TYPE, group, 27279ec29343SJun Yang &local_cfg); 27289ec29343SJun Yang return ret; 27299ec29343SJun Yang } 27309ec29343SJun Yang 2731200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM, 2732200a33e4SJun Yang DPAA2_FLOW_QOS_TYPE, group, 2733200a33e4SJun Yang &local_cfg); 2734200a33e4SJun Yang if (ret) 273556c1817dSJun Yang return ret; 273656c1817dSJun Yang 2737200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM, 2738200a33e4SJun Yang DPAA2_FLOW_FS_TYPE, group, &local_cfg); 2739200a33e4SJun Yang if (ret) 2740200a33e4SJun Yang return ret; 2741200a33e4SJun Yang 2742200a33e4SJun Yang if (!spec_ipv6) { 2743200a33e4SJun Yang (*device_configured) |= local_cfg; 274456c1817dSJun Yang return 0; 2745200a33e4SJun Yang } 274656c1817dSJun Yang 27474cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv6, 27484cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_IPV6); 27494cc5cf4aSJun Yang if (ret) { 275056c1817dSJun Yang DPAA2_PMD_WARN("Extract field(s) of IPv6 not support."); 27514cc5cf4aSJun Yang return ret; 275256c1817dSJun Yang } 275356c1817dSJun Yang 275456c1817dSJun Yang if (memcmp((const char *)&mask_ipv6->hdr.src_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) { 275556c1817dSJun Yang key = &spec_ipv6->hdr.src_addr; 275656c1817dSJun Yang mask = &mask_ipv6->hdr.src_addr; 275756c1817dSJun Yang size = NH_FLD_IPV6_ADDR_SIZE; 275856c1817dSJun Yang 275956c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6, 276056c1817dSJun Yang NH_FLD_IPV6_SRC_IP, 276156c1817dSJun Yang key, mask, size, priv, 276256c1817dSJun Yang group, &local_cfg, 276356c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 276456c1817dSJun Yang if (ret) 276556c1817dSJun Yang return ret; 276656c1817dSJun Yang 276756c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6, 276856c1817dSJun Yang NH_FLD_IPV6_SRC_IP, 276956c1817dSJun Yang key, mask, size, priv, 277056c1817dSJun Yang group, &local_cfg, 277156c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 277256c1817dSJun Yang if (ret) 277356c1817dSJun Yang return ret; 277456c1817dSJun Yang } 277556c1817dSJun Yang 277656c1817dSJun Yang if (memcmp((const char *)&mask_ipv6->hdr.dst_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) { 277756c1817dSJun Yang key = &spec_ipv6->hdr.dst_addr; 277856c1817dSJun Yang mask = &mask_ipv6->hdr.dst_addr; 277956c1817dSJun Yang size = NH_FLD_IPV6_ADDR_SIZE; 278056c1817dSJun Yang 278156c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6, 278256c1817dSJun Yang NH_FLD_IPV6_DST_IP, 278356c1817dSJun Yang key, mask, size, priv, 278456c1817dSJun Yang group, &local_cfg, 278556c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 278656c1817dSJun Yang if (ret) 278756c1817dSJun Yang return ret; 278856c1817dSJun Yang 278956c1817dSJun Yang ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6, 279056c1817dSJun Yang NH_FLD_IPV6_DST_IP, 279156c1817dSJun Yang key, mask, size, priv, 279256c1817dSJun Yang group, &local_cfg, 279356c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 279456c1817dSJun Yang if (ret) 279556c1817dSJun Yang return ret; 279656c1817dSJun Yang } 279756c1817dSJun Yang 279856c1817dSJun Yang if (mask_ipv6->hdr.proto) { 279956c1817dSJun Yang key = &spec_ipv6->hdr.proto; 280056c1817dSJun Yang mask = &mask_ipv6->hdr.proto; 280156c1817dSJun Yang size = sizeof(uint8_t); 280256c1817dSJun Yang 280356c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP, 280456c1817dSJun Yang NH_FLD_IP_PROTO, key, 280556c1817dSJun Yang mask, size, priv, group, 280656c1817dSJun Yang &local_cfg, 280756c1817dSJun Yang DPAA2_FLOW_QOS_TYPE); 280856c1817dSJun Yang if (ret) 280956c1817dSJun Yang return ret; 281056c1817dSJun Yang 281156c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP, 281256c1817dSJun Yang NH_FLD_IP_PROTO, key, 281356c1817dSJun Yang mask, size, priv, group, 281456c1817dSJun Yang &local_cfg, 281556c1817dSJun Yang DPAA2_FLOW_FS_TYPE); 281656c1817dSJun Yang if (ret) 281756c1817dSJun Yang return ret; 281856c1817dSJun Yang } 281956c1817dSJun Yang 282056c1817dSJun Yang (*device_configured) |= local_cfg; 282156c1817dSJun Yang return 0; 282256c1817dSJun Yang } 282356c1817dSJun Yang 282456c1817dSJun Yang static int 282556c1817dSJun Yang dpaa2_configure_flow_icmp(struct dpaa2_dev_flow *flow, 2826fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 2827fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 28289ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 2829fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 28305f176728SJun Yang struct rte_flow_error *error __rte_unused, 28315f176728SJun Yang int *device_configured) 2832fe2b986aSSunil Kumar Kori { 283356c1817dSJun Yang int ret, local_cfg = 0; 2834fe2b986aSSunil Kumar Kori uint32_t group; 2835fe2b986aSSunil Kumar Kori const struct rte_flow_item_icmp *spec, *mask; 2836fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 28379ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 2838fe2b986aSSunil Kumar Kori 2839fe2b986aSSunil Kumar Kori group = attr->group; 2840fe2b986aSSunil Kumar Kori 2841fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 284256c1817dSJun Yang spec = pattern->spec; 284356c1817dSJun Yang mask = pattern->mask ? 284456c1817dSJun Yang pattern->mask : &dpaa2_flow_item_icmp_mask; 2845fe2b986aSSunil Kumar Kori 28465f176728SJun Yang /* Get traffic class index and flow id to be configured */ 28475f176728SJun Yang flow->tc_id = group; 28485f176728SJun Yang flow->tc_index = attr->priority; 2849fe2b986aSSunil Kumar Kori 28509ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 28519ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-ICMP distribution not support"); 28529ec29343SJun Yang return -ENOTSUP; 28539ec29343SJun Yang } 28549ec29343SJun Yang 28555f176728SJun Yang if (!spec) { 2856200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2857200a33e4SJun Yang FAF_ICMP_FRAM, DPAA2_FLOW_QOS_TYPE, 2858200a33e4SJun Yang group, &local_cfg); 2859200a33e4SJun Yang if (ret) 2860200a33e4SJun Yang return ret; 2861fe2b986aSSunil Kumar Kori 2862200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2863200a33e4SJun Yang FAF_ICMP_FRAM, DPAA2_FLOW_FS_TYPE, 286456c1817dSJun Yang group, &local_cfg); 286556c1817dSJun Yang if (ret) 286656c1817dSJun Yang return ret; 28675f176728SJun Yang 28685f176728SJun Yang (*device_configured) |= local_cfg; 28695f176728SJun Yang return 0; 28705f176728SJun Yang } 28715f176728SJun Yang 28724cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 28734cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ICMP); 28744cc5cf4aSJun Yang if (ret) { 2875926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of ICMP not support."); 2876926c1279SJun Yang 28774cc5cf4aSJun Yang return ret; 2878926c1279SJun Yang } 2879926c1279SJun Yang 28805f176728SJun Yang if (mask->hdr.icmp_type) { 288156c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP, 288256c1817dSJun Yang NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type, 288356c1817dSJun Yang &mask->hdr.icmp_type, sizeof(uint8_t), 288456c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 288556c1817dSJun Yang if (ret) 288656c1817dSJun Yang return ret; 28875f176728SJun Yang 288856c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP, 288956c1817dSJun Yang NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type, 289056c1817dSJun Yang &mask->hdr.icmp_type, sizeof(uint8_t), 289156c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 289256c1817dSJun Yang if (ret) 289356c1817dSJun Yang return ret; 28945f176728SJun Yang } 28955f176728SJun Yang 28965f176728SJun Yang if (mask->hdr.icmp_code) { 289756c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP, 289856c1817dSJun Yang NH_FLD_ICMP_CODE, &spec->hdr.icmp_code, 289956c1817dSJun Yang &mask->hdr.icmp_code, sizeof(uint8_t), 290056c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 290156c1817dSJun Yang if (ret) 290256c1817dSJun Yang return ret; 29035f176728SJun Yang 290456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP, 290556c1817dSJun Yang NH_FLD_ICMP_CODE, &spec->hdr.icmp_code, 290656c1817dSJun Yang &mask->hdr.icmp_code, sizeof(uint8_t), 290756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 290856c1817dSJun Yang if (ret) 290956c1817dSJun Yang return ret; 29105f176728SJun Yang } 29115f176728SJun Yang 29125f176728SJun Yang (*device_configured) |= local_cfg; 29135f176728SJun Yang 29145f176728SJun Yang return 0; 2915fe2b986aSSunil Kumar Kori } 2916fe2b986aSSunil Kumar Kori 2917fe2b986aSSunil Kumar Kori static int 291856c1817dSJun Yang dpaa2_configure_flow_udp(struct dpaa2_dev_flow *flow, 2919fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 2920fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 29219ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 2922fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 29235f176728SJun Yang struct rte_flow_error *error __rte_unused, 29245f176728SJun Yang int *device_configured) 2925fe2b986aSSunil Kumar Kori { 292656c1817dSJun Yang int ret, local_cfg = 0; 2927fe2b986aSSunil Kumar Kori uint32_t group; 2928fe2b986aSSunil Kumar Kori const struct rte_flow_item_udp *spec, *mask; 2929fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 29309ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 2931fe2b986aSSunil Kumar Kori 2932fe2b986aSSunil Kumar Kori group = attr->group; 2933fe2b986aSSunil Kumar Kori 2934fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 293556c1817dSJun Yang spec = pattern->spec; 293656c1817dSJun Yang mask = pattern->mask ? 293756c1817dSJun Yang pattern->mask : &dpaa2_flow_item_udp_mask; 2938fe2b986aSSunil Kumar Kori 29395f176728SJun Yang /* Get traffic class index and flow id to be configured */ 29405f176728SJun Yang flow->tc_id = group; 29415f176728SJun Yang flow->tc_index = attr->priority; 2942fe2b986aSSunil Kumar Kori 29439ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 29449ec29343SJun Yang if (spec) { 29459ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-UDP distribution not support"); 29469ec29343SJun Yang return -ENOTSUP; 29479ec29343SJun Yang } 29489ec29343SJun Yang 29499ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 29509ec29343SJun Yang FAFE_VXLAN_IN_UDP_FRAM, 29519ec29343SJun Yang DPAA2_FLOW_QOS_TYPE, group, 29529ec29343SJun Yang &local_cfg); 29539ec29343SJun Yang if (ret) 29549ec29343SJun Yang return ret; 29559ec29343SJun Yang 29569ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 29579ec29343SJun Yang FAFE_VXLAN_IN_UDP_FRAM, 29589ec29343SJun Yang DPAA2_FLOW_FS_TYPE, group, 29599ec29343SJun Yang &local_cfg); 29609ec29343SJun Yang return ret; 29619ec29343SJun Yang } 29629ec29343SJun Yang 2963200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2964200a33e4SJun Yang FAF_UDP_FRAM, DPAA2_FLOW_QOS_TYPE, 296556c1817dSJun Yang group, &local_cfg); 296656c1817dSJun Yang if (ret) 296756c1817dSJun Yang return ret; 29685f176728SJun Yang 2969200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 2970200a33e4SJun Yang FAF_UDP_FRAM, DPAA2_FLOW_FS_TYPE, 2971200a33e4SJun Yang group, &local_cfg); 2972200a33e4SJun Yang if (ret) 2973200a33e4SJun Yang return ret; 29745f176728SJun Yang 2975200a33e4SJun Yang if (!spec) { 2976200a33e4SJun Yang (*device_configured) |= local_cfg; 29775f176728SJun Yang return 0; 29785f176728SJun Yang } 29795f176728SJun Yang 29804cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 29814cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_UDP); 29824cc5cf4aSJun Yang if (ret) { 2983926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of UDP not support."); 2984926c1279SJun Yang 29854cc5cf4aSJun Yang return ret; 2986926c1279SJun Yang } 2987926c1279SJun Yang 29885f176728SJun Yang if (mask->hdr.src_port) { 298956c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP, 299056c1817dSJun Yang NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port, 299156c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 299256c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 299356c1817dSJun Yang if (ret) 299456c1817dSJun Yang return ret; 29955f176728SJun Yang 299656c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP, 299756c1817dSJun Yang NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port, 299856c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 299956c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 300056c1817dSJun Yang if (ret) 300156c1817dSJun Yang return ret; 30025f176728SJun Yang } 30035f176728SJun Yang 30045f176728SJun Yang if (mask->hdr.dst_port) { 300556c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP, 300656c1817dSJun Yang NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port, 300756c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 300856c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 300956c1817dSJun Yang if (ret) 301056c1817dSJun Yang return ret; 30115f176728SJun Yang 301256c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP, 301356c1817dSJun Yang NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port, 301456c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 301556c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 301656c1817dSJun Yang if (ret) 301756c1817dSJun Yang return ret; 30185f176728SJun Yang } 30195f176728SJun Yang 30205f176728SJun Yang (*device_configured) |= local_cfg; 30215f176728SJun Yang 30225f176728SJun Yang return 0; 3023fe2b986aSSunil Kumar Kori } 3024fe2b986aSSunil Kumar Kori 3025fe2b986aSSunil Kumar Kori static int 302656c1817dSJun Yang dpaa2_configure_flow_tcp(struct dpaa2_dev_flow *flow, 3027fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 3028fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 30299ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 3030fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 30315f176728SJun Yang struct rte_flow_error *error __rte_unused, 30325f176728SJun Yang int *device_configured) 3033fe2b986aSSunil Kumar Kori { 303456c1817dSJun Yang int ret, local_cfg = 0; 3035fe2b986aSSunil Kumar Kori uint32_t group; 3036fe2b986aSSunil Kumar Kori const struct rte_flow_item_tcp *spec, *mask; 3037fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 30389ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 3039fe2b986aSSunil Kumar Kori 3040fe2b986aSSunil Kumar Kori group = attr->group; 3041fe2b986aSSunil Kumar Kori 3042fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 304356c1817dSJun Yang spec = pattern->spec; 304456c1817dSJun Yang mask = pattern->mask ? 304556c1817dSJun Yang pattern->mask : &dpaa2_flow_item_tcp_mask; 3046fe2b986aSSunil Kumar Kori 30475f176728SJun Yang /* Get traffic class index and flow id to be configured */ 30485f176728SJun Yang flow->tc_id = group; 30495f176728SJun Yang flow->tc_index = attr->priority; 3050fe2b986aSSunil Kumar Kori 30519ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 30529ec29343SJun Yang if (spec) { 30539ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-TCP distribution not support"); 30549ec29343SJun Yang return -ENOTSUP; 30559ec29343SJun Yang } 30569ec29343SJun Yang 30579ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 30589ec29343SJun Yang FAFE_VXLAN_IN_TCP_FRAM, 30599ec29343SJun Yang DPAA2_FLOW_QOS_TYPE, group, 30609ec29343SJun Yang &local_cfg); 30619ec29343SJun Yang if (ret) 30629ec29343SJun Yang return ret; 30639ec29343SJun Yang 30649ec29343SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 30659ec29343SJun Yang FAFE_VXLAN_IN_TCP_FRAM, 30669ec29343SJun Yang DPAA2_FLOW_FS_TYPE, group, 30679ec29343SJun Yang &local_cfg); 30689ec29343SJun Yang return ret; 30699ec29343SJun Yang } 30709ec29343SJun Yang 3071200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3072200a33e4SJun Yang FAF_TCP_FRAM, DPAA2_FLOW_QOS_TYPE, 307356c1817dSJun Yang group, &local_cfg); 307456c1817dSJun Yang if (ret) 307556c1817dSJun Yang return ret; 30765f176728SJun Yang 3077200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3078200a33e4SJun Yang FAF_TCP_FRAM, DPAA2_FLOW_FS_TYPE, 3079200a33e4SJun Yang group, &local_cfg); 3080200a33e4SJun Yang if (ret) 3081200a33e4SJun Yang return ret; 30825f176728SJun Yang 3083200a33e4SJun Yang if (!spec) { 3084200a33e4SJun Yang (*device_configured) |= local_cfg; 30855f176728SJun Yang return 0; 30865f176728SJun Yang } 30875f176728SJun Yang 30884cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 30894cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_TCP); 30904cc5cf4aSJun Yang if (ret) { 3091926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of TCP not support."); 3092926c1279SJun Yang 30934cc5cf4aSJun Yang return ret; 3094926c1279SJun Yang } 3095926c1279SJun Yang 30965f176728SJun Yang if (mask->hdr.src_port) { 309756c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP, 309856c1817dSJun Yang NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port, 309956c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 310056c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 310156c1817dSJun Yang if (ret) 310256c1817dSJun Yang return ret; 31035f176728SJun Yang 310456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP, 310556c1817dSJun Yang NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port, 310656c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 310756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 310856c1817dSJun Yang if (ret) 310956c1817dSJun Yang return ret; 31105f176728SJun Yang } 31115f176728SJun Yang 31125f176728SJun Yang if (mask->hdr.dst_port) { 311356c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP, 311456c1817dSJun Yang NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port, 311556c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 311656c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 311756c1817dSJun Yang if (ret) 311856c1817dSJun Yang return ret; 31195f176728SJun Yang 312056c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP, 312156c1817dSJun Yang NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port, 312256c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 312356c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 312456c1817dSJun Yang if (ret) 312556c1817dSJun Yang return ret; 31265f176728SJun Yang } 31275f176728SJun Yang 31285f176728SJun Yang (*device_configured) |= local_cfg; 31295f176728SJun Yang 31305f176728SJun Yang return 0; 3131fe2b986aSSunil Kumar Kori } 3132fe2b986aSSunil Kumar Kori 3133fe2b986aSSunil Kumar Kori static int 31344cc5cf4aSJun Yang dpaa2_configure_flow_esp(struct dpaa2_dev_flow *flow, 31354cc5cf4aSJun Yang struct rte_eth_dev *dev, 31364cc5cf4aSJun Yang const struct rte_flow_attr *attr, 31374cc5cf4aSJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 31384cc5cf4aSJun Yang const struct rte_flow_action actions[] __rte_unused, 31394cc5cf4aSJun Yang struct rte_flow_error *error __rte_unused, 31404cc5cf4aSJun Yang int *device_configured) 31414cc5cf4aSJun Yang { 31424cc5cf4aSJun Yang int ret, local_cfg = 0; 31434cc5cf4aSJun Yang uint32_t group; 31444cc5cf4aSJun Yang const struct rte_flow_item_esp *spec, *mask; 31454cc5cf4aSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 31464cc5cf4aSJun Yang const struct rte_flow_item *pattern = 31474cc5cf4aSJun Yang &dpaa2_pattern->generic_item; 31484cc5cf4aSJun Yang 31494cc5cf4aSJun Yang group = attr->group; 31504cc5cf4aSJun Yang 31514cc5cf4aSJun Yang /* Parse pattern list to get the matching parameters */ 31524cc5cf4aSJun Yang spec = pattern->spec; 31534cc5cf4aSJun Yang mask = pattern->mask ? 31544cc5cf4aSJun Yang pattern->mask : &dpaa2_flow_item_esp_mask; 31554cc5cf4aSJun Yang 31564cc5cf4aSJun Yang /* Get traffic class index and flow id to be configured */ 31574cc5cf4aSJun Yang flow->tc_id = group; 31584cc5cf4aSJun Yang flow->tc_index = attr->priority; 31594cc5cf4aSJun Yang 31604cc5cf4aSJun Yang if (dpaa2_pattern->in_tunnel) { 31614cc5cf4aSJun Yang DPAA2_PMD_ERR("Tunnel-ESP distribution not support"); 31624cc5cf4aSJun Yang return -ENOTSUP; 31634cc5cf4aSJun Yang } 31644cc5cf4aSJun Yang 31654cc5cf4aSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 31664cc5cf4aSJun Yang FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_QOS_TYPE, 31674cc5cf4aSJun Yang group, &local_cfg); 31684cc5cf4aSJun Yang if (ret) 31694cc5cf4aSJun Yang return ret; 31704cc5cf4aSJun Yang 31714cc5cf4aSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 31724cc5cf4aSJun Yang FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_FS_TYPE, 31734cc5cf4aSJun Yang group, &local_cfg); 31744cc5cf4aSJun Yang if (ret) 31754cc5cf4aSJun Yang return ret; 31764cc5cf4aSJun Yang 31774cc5cf4aSJun Yang if (!spec) { 31784cc5cf4aSJun Yang (*device_configured) |= local_cfg; 31794cc5cf4aSJun Yang return 0; 31804cc5cf4aSJun Yang } 31814cc5cf4aSJun Yang 31824cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 31834cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ESP); 31844cc5cf4aSJun Yang if (ret) { 31854cc5cf4aSJun Yang DPAA2_PMD_WARN("Extract field(s) of ESP not support."); 31864cc5cf4aSJun Yang 31874cc5cf4aSJun Yang return ret; 31884cc5cf4aSJun Yang } 31894cc5cf4aSJun Yang 31904cc5cf4aSJun Yang if (mask->hdr.spi) { 31914cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP, 31924cc5cf4aSJun Yang NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi, 31934cc5cf4aSJun Yang &mask->hdr.spi, sizeof(rte_be32_t), 31944cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 31954cc5cf4aSJun Yang if (ret) 31964cc5cf4aSJun Yang return ret; 31974cc5cf4aSJun Yang 31984cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP, 31994cc5cf4aSJun Yang NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi, 32004cc5cf4aSJun Yang &mask->hdr.spi, sizeof(rte_be32_t), 32014cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 32024cc5cf4aSJun Yang if (ret) 32034cc5cf4aSJun Yang return ret; 32044cc5cf4aSJun Yang } 32054cc5cf4aSJun Yang 32064cc5cf4aSJun Yang if (mask->hdr.seq) { 32074cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP, 32084cc5cf4aSJun Yang NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq, 32094cc5cf4aSJun Yang &mask->hdr.seq, sizeof(rte_be32_t), 32104cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 32114cc5cf4aSJun Yang if (ret) 32124cc5cf4aSJun Yang return ret; 32134cc5cf4aSJun Yang 32144cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP, 32154cc5cf4aSJun Yang NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq, 32164cc5cf4aSJun Yang &mask->hdr.seq, sizeof(rte_be32_t), 32174cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 32184cc5cf4aSJun Yang if (ret) 32194cc5cf4aSJun Yang return ret; 32204cc5cf4aSJun Yang } 32214cc5cf4aSJun Yang 32224cc5cf4aSJun Yang (*device_configured) |= local_cfg; 32234cc5cf4aSJun Yang 32244cc5cf4aSJun Yang return 0; 32254cc5cf4aSJun Yang } 32264cc5cf4aSJun Yang 32274cc5cf4aSJun Yang static int 32284cc5cf4aSJun Yang dpaa2_configure_flow_ah(struct dpaa2_dev_flow *flow, 32294cc5cf4aSJun Yang struct rte_eth_dev *dev, 32304cc5cf4aSJun Yang const struct rte_flow_attr *attr, 32314cc5cf4aSJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 32324cc5cf4aSJun Yang const struct rte_flow_action actions[] __rte_unused, 32334cc5cf4aSJun Yang struct rte_flow_error *error __rte_unused, 32344cc5cf4aSJun Yang int *device_configured) 32354cc5cf4aSJun Yang { 32364cc5cf4aSJun Yang int ret, local_cfg = 0; 32374cc5cf4aSJun Yang uint32_t group; 32384cc5cf4aSJun Yang const struct rte_flow_item_ah *spec, *mask; 32394cc5cf4aSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 32404cc5cf4aSJun Yang const struct rte_flow_item *pattern = 32414cc5cf4aSJun Yang &dpaa2_pattern->generic_item; 32424cc5cf4aSJun Yang 32434cc5cf4aSJun Yang group = attr->group; 32444cc5cf4aSJun Yang 32454cc5cf4aSJun Yang /* Parse pattern list to get the matching parameters */ 32464cc5cf4aSJun Yang spec = pattern->spec; 32474cc5cf4aSJun Yang mask = pattern->mask ? 32484cc5cf4aSJun Yang pattern->mask : &dpaa2_flow_item_ah_mask; 32494cc5cf4aSJun Yang 32504cc5cf4aSJun Yang /* Get traffic class index and flow id to be configured */ 32514cc5cf4aSJun Yang flow->tc_id = group; 32524cc5cf4aSJun Yang flow->tc_index = attr->priority; 32534cc5cf4aSJun Yang 32544cc5cf4aSJun Yang if (dpaa2_pattern->in_tunnel) { 32554cc5cf4aSJun Yang DPAA2_PMD_ERR("Tunnel-AH distribution not support"); 32564cc5cf4aSJun Yang return -ENOTSUP; 32574cc5cf4aSJun Yang } 32584cc5cf4aSJun Yang 32594cc5cf4aSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 32604cc5cf4aSJun Yang FAF_IPSEC_AH_FRAM, DPAA2_FLOW_QOS_TYPE, 32614cc5cf4aSJun Yang group, &local_cfg); 32624cc5cf4aSJun Yang if (ret) 32634cc5cf4aSJun Yang return ret; 32644cc5cf4aSJun Yang 32654cc5cf4aSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 32664cc5cf4aSJun Yang FAF_IPSEC_AH_FRAM, DPAA2_FLOW_FS_TYPE, 32674cc5cf4aSJun Yang group, &local_cfg); 32684cc5cf4aSJun Yang if (ret) 32694cc5cf4aSJun Yang return ret; 32704cc5cf4aSJun Yang 32714cc5cf4aSJun Yang if (!spec) { 32724cc5cf4aSJun Yang (*device_configured) |= local_cfg; 32734cc5cf4aSJun Yang return 0; 32744cc5cf4aSJun Yang } 32754cc5cf4aSJun Yang 32764cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 32774cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_AH); 32784cc5cf4aSJun Yang if (ret) { 32794cc5cf4aSJun Yang DPAA2_PMD_WARN("Extract field(s) of AH not support."); 32804cc5cf4aSJun Yang 32814cc5cf4aSJun Yang return ret; 32824cc5cf4aSJun Yang } 32834cc5cf4aSJun Yang 32844cc5cf4aSJun Yang if (mask->spi) { 32854cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH, 32864cc5cf4aSJun Yang NH_FLD_IPSEC_AH_SPI, &spec->spi, 32874cc5cf4aSJun Yang &mask->spi, sizeof(rte_be32_t), 32884cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 32894cc5cf4aSJun Yang if (ret) 32904cc5cf4aSJun Yang return ret; 32914cc5cf4aSJun Yang 32924cc5cf4aSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH, 32934cc5cf4aSJun Yang NH_FLD_IPSEC_AH_SPI, &spec->spi, 32944cc5cf4aSJun Yang &mask->spi, sizeof(rte_be32_t), 32954cc5cf4aSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 32964cc5cf4aSJun Yang if (ret) 32974cc5cf4aSJun Yang return ret; 32984cc5cf4aSJun Yang } 32994cc5cf4aSJun Yang 33004cc5cf4aSJun Yang if (mask->seq_num) { 33014cc5cf4aSJun Yang DPAA2_PMD_ERR("AH seq distribution not support"); 33024cc5cf4aSJun Yang return -ENOTSUP; 33034cc5cf4aSJun Yang } 33044cc5cf4aSJun Yang 33054cc5cf4aSJun Yang (*device_configured) |= local_cfg; 33064cc5cf4aSJun Yang 33074cc5cf4aSJun Yang return 0; 33084cc5cf4aSJun Yang } 33094cc5cf4aSJun Yang 33104cc5cf4aSJun Yang static int 331156c1817dSJun Yang dpaa2_configure_flow_sctp(struct dpaa2_dev_flow *flow, 3312fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 3313fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 33149ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 3315fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 33165f176728SJun Yang struct rte_flow_error *error __rte_unused, 33175f176728SJun Yang int *device_configured) 3318fe2b986aSSunil Kumar Kori { 331956c1817dSJun Yang int ret, local_cfg = 0; 3320fe2b986aSSunil Kumar Kori uint32_t group; 3321fe2b986aSSunil Kumar Kori const struct rte_flow_item_sctp *spec, *mask; 3322fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 33239ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 3324fe2b986aSSunil Kumar Kori 3325fe2b986aSSunil Kumar Kori group = attr->group; 3326fe2b986aSSunil Kumar Kori 3327fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 332856c1817dSJun Yang spec = pattern->spec; 332956c1817dSJun Yang mask = pattern->mask ? 333056c1817dSJun Yang pattern->mask : &dpaa2_flow_item_sctp_mask; 3331fe2b986aSSunil Kumar Kori 33325f176728SJun Yang /* Get traffic class index and flow id to be configured */ 33335f176728SJun Yang flow->tc_id = group; 33345f176728SJun Yang flow->tc_index = attr->priority; 3335fe2b986aSSunil Kumar Kori 33369ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 33379ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-SCTP distribution not support"); 33389ec29343SJun Yang return -ENOTSUP; 33399ec29343SJun Yang } 33409ec29343SJun Yang 3341200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3342200a33e4SJun Yang FAF_SCTP_FRAM, DPAA2_FLOW_QOS_TYPE, 334356c1817dSJun Yang group, &local_cfg); 334456c1817dSJun Yang if (ret) 334556c1817dSJun Yang return ret; 33465f176728SJun Yang 3347200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3348200a33e4SJun Yang FAF_SCTP_FRAM, DPAA2_FLOW_FS_TYPE, 3349200a33e4SJun Yang group, &local_cfg); 3350200a33e4SJun Yang if (ret) 3351200a33e4SJun Yang return ret; 33525f176728SJun Yang 3353200a33e4SJun Yang if (!spec) { 3354200a33e4SJun Yang (*device_configured) |= local_cfg; 33555f176728SJun Yang return 0; 33565f176728SJun Yang } 33575f176728SJun Yang 33584cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 33594cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_SCTP); 33604cc5cf4aSJun Yang if (ret) { 3361926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of SCTP not support."); 3362926c1279SJun Yang 33634cc5cf4aSJun Yang return ret; 3364926c1279SJun Yang } 3365926c1279SJun Yang 33665f176728SJun Yang if (mask->hdr.src_port) { 336756c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP, 336856c1817dSJun Yang NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port, 336956c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 337056c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 337156c1817dSJun Yang if (ret) 337256c1817dSJun Yang return ret; 33735f176728SJun Yang 337456c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP, 337556c1817dSJun Yang NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port, 337656c1817dSJun Yang &mask->hdr.src_port, sizeof(rte_be16_t), 337756c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 337856c1817dSJun Yang if (ret) 337956c1817dSJun Yang return ret; 33805f176728SJun Yang } 33815f176728SJun Yang 33825f176728SJun Yang if (mask->hdr.dst_port) { 338356c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP, 338456c1817dSJun Yang NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port, 338556c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 338656c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 338756c1817dSJun Yang if (ret) 338856c1817dSJun Yang return ret; 33895f176728SJun Yang 339056c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP, 339156c1817dSJun Yang NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port, 339256c1817dSJun Yang &mask->hdr.dst_port, sizeof(rte_be16_t), 339356c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 339456c1817dSJun Yang if (ret) 339556c1817dSJun Yang return ret; 33965f176728SJun Yang } 33975f176728SJun Yang 33985f176728SJun Yang (*device_configured) |= local_cfg; 33995f176728SJun Yang 34005f176728SJun Yang return 0; 3401fe2b986aSSunil Kumar Kori } 3402fe2b986aSSunil Kumar Kori 3403fe2b986aSSunil Kumar Kori static int 340456c1817dSJun Yang dpaa2_configure_flow_gre(struct dpaa2_dev_flow *flow, 3405fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 3406fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 34079ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 3408fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[] __rte_unused, 34095f176728SJun Yang struct rte_flow_error *error __rte_unused, 34105f176728SJun Yang int *device_configured) 3411fe2b986aSSunil Kumar Kori { 341256c1817dSJun Yang int ret, local_cfg = 0; 3413fe2b986aSSunil Kumar Kori uint32_t group; 3414fe2b986aSSunil Kumar Kori const struct rte_flow_item_gre *spec, *mask; 3415fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 34169ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 3417fe2b986aSSunil Kumar Kori 3418fe2b986aSSunil Kumar Kori group = attr->group; 3419fe2b986aSSunil Kumar Kori 3420fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 342156c1817dSJun Yang spec = pattern->spec; 342256c1817dSJun Yang mask = pattern->mask ? 342356c1817dSJun Yang pattern->mask : &dpaa2_flow_item_gre_mask; 3424fe2b986aSSunil Kumar Kori 34255f176728SJun Yang /* Get traffic class index and flow id to be configured */ 34265f176728SJun Yang flow->tc_id = group; 34275f176728SJun Yang flow->tc_index = attr->priority; 34285f176728SJun Yang 34299ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 34309ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-GRE distribution not support"); 34319ec29343SJun Yang return -ENOTSUP; 34329ec29343SJun Yang } 34339ec29343SJun Yang 34345f176728SJun Yang if (!spec) { 3435200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3436200a33e4SJun Yang FAF_GRE_FRAM, DPAA2_FLOW_QOS_TYPE, 3437200a33e4SJun Yang group, &local_cfg); 3438200a33e4SJun Yang if (ret) 3439200a33e4SJun Yang return ret; 34405f176728SJun Yang 3441200a33e4SJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3442200a33e4SJun Yang FAF_GRE_FRAM, DPAA2_FLOW_FS_TYPE, 344356c1817dSJun Yang group, &local_cfg); 344456c1817dSJun Yang if (ret) 344556c1817dSJun Yang return ret; 34465f176728SJun Yang 34475f176728SJun Yang (*device_configured) |= local_cfg; 34485f176728SJun Yang return 0; 34495f176728SJun Yang } 34505f176728SJun Yang 34514cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 34524cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_GRE); 34534cc5cf4aSJun Yang if (ret) { 3454926c1279SJun Yang DPAA2_PMD_WARN("Extract field(s) of GRE not support."); 3455926c1279SJun Yang 34564cc5cf4aSJun Yang return ret; 3457926c1279SJun Yang } 3458926c1279SJun Yang 34595f176728SJun Yang if (!mask->protocol) 34605f176728SJun Yang return 0; 34615f176728SJun Yang 346256c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE, 346356c1817dSJun Yang NH_FLD_GRE_TYPE, &spec->protocol, 346456c1817dSJun Yang &mask->protocol, sizeof(rte_be16_t), 346556c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 346656c1817dSJun Yang if (ret) 346756c1817dSJun Yang return ret; 3468fe2b986aSSunil Kumar Kori 346956c1817dSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE, 347056c1817dSJun Yang NH_FLD_GRE_TYPE, &spec->protocol, 347156c1817dSJun Yang &mask->protocol, sizeof(rte_be16_t), 347256c1817dSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 347356c1817dSJun Yang if (ret) 347456c1817dSJun Yang return ret; 34755f176728SJun Yang 34765f176728SJun Yang (*device_configured) |= local_cfg; 34775f176728SJun Yang 34785f176728SJun Yang return 0; 34795f176728SJun Yang } 34805f176728SJun Yang 34813f881f8dSNipun Gupta static int 348239c8044fSJun Yang dpaa2_configure_flow_vxlan(struct dpaa2_dev_flow *flow, 348339c8044fSJun Yang struct rte_eth_dev *dev, 348439c8044fSJun Yang const struct rte_flow_attr *attr, 34859ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 348639c8044fSJun Yang const struct rte_flow_action actions[] __rte_unused, 348739c8044fSJun Yang struct rte_flow_error *error __rte_unused, 348839c8044fSJun Yang int *device_configured) 348939c8044fSJun Yang { 349039c8044fSJun Yang int ret, local_cfg = 0; 349139c8044fSJun Yang uint32_t group; 349239c8044fSJun Yang const struct rte_flow_item_vxlan *spec, *mask; 349339c8044fSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 34949ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 349539c8044fSJun Yang 349639c8044fSJun Yang group = attr->group; 349739c8044fSJun Yang 349839c8044fSJun Yang /* Parse pattern list to get the matching parameters */ 349939c8044fSJun Yang spec = pattern->spec; 350039c8044fSJun Yang mask = pattern->mask ? 350139c8044fSJun Yang pattern->mask : &dpaa2_flow_item_vxlan_mask; 350239c8044fSJun Yang 350339c8044fSJun Yang /* Get traffic class index and flow id to be configured */ 350439c8044fSJun Yang flow->tc_id = group; 350539c8044fSJun Yang flow->tc_index = attr->priority; 350639c8044fSJun Yang 35079ec29343SJun Yang if (dpaa2_pattern->in_tunnel) { 35089ec29343SJun Yang DPAA2_PMD_ERR("Tunnel-VXLAN distribution not support"); 35099ec29343SJun Yang return -ENOTSUP; 35109ec29343SJun Yang } 35119ec29343SJun Yang 351239c8044fSJun Yang if (!spec) { 351339c8044fSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 351439c8044fSJun Yang FAF_VXLAN_FRAM, DPAA2_FLOW_QOS_TYPE, 351539c8044fSJun Yang group, &local_cfg); 351639c8044fSJun Yang if (ret) 351739c8044fSJun Yang return ret; 351839c8044fSJun Yang 351939c8044fSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 352039c8044fSJun Yang FAF_VXLAN_FRAM, DPAA2_FLOW_FS_TYPE, 352139c8044fSJun Yang group, &local_cfg); 352239c8044fSJun Yang if (ret) 352339c8044fSJun Yang return ret; 352439c8044fSJun Yang 352539c8044fSJun Yang (*device_configured) |= local_cfg; 352639c8044fSJun Yang return 0; 352739c8044fSJun Yang } 352839c8044fSJun Yang 35294cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 35304cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_VXLAN); 35314cc5cf4aSJun Yang if (ret) { 353239c8044fSJun Yang DPAA2_PMD_WARN("Extract field(s) of VXLAN not support."); 353339c8044fSJun Yang 35344cc5cf4aSJun Yang return ret; 353539c8044fSJun Yang } 353639c8044fSJun Yang 353739c8044fSJun Yang if (mask->flags) { 353839c8044fSJun Yang if (spec->flags != VXLAN_HF_VNI) { 353939c8044fSJun Yang DPAA2_PMD_ERR("vxlan flag(0x%02x) must be 0x%02x.", 354039c8044fSJun Yang spec->flags, VXLAN_HF_VNI); 354139c8044fSJun Yang return -EINVAL; 354239c8044fSJun Yang } 354339c8044fSJun Yang if (mask->flags != 0xff) { 354439c8044fSJun Yang DPAA2_PMD_ERR("Not support to extract vxlan flag."); 354539c8044fSJun Yang return -EINVAL; 354639c8044fSJun Yang } 354739c8044fSJun Yang } 354839c8044fSJun Yang 354939c8044fSJun Yang if (mask->vni[0] || mask->vni[1] || mask->vni[2]) { 355039c8044fSJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 355139c8044fSJun Yang DPAA2_VXLAN_VNI_OFFSET, 355239c8044fSJun Yang sizeof(mask->vni), spec->vni, 355339c8044fSJun Yang mask->vni, 355439c8044fSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 355539c8044fSJun Yang if (ret) 355639c8044fSJun Yang return ret; 355739c8044fSJun Yang 355839c8044fSJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 355939c8044fSJun Yang DPAA2_VXLAN_VNI_OFFSET, 356039c8044fSJun Yang sizeof(mask->vni), spec->vni, 356139c8044fSJun Yang mask->vni, 356239c8044fSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 356339c8044fSJun Yang if (ret) 356439c8044fSJun Yang return ret; 356539c8044fSJun Yang } 356639c8044fSJun Yang 356739c8044fSJun Yang (*device_configured) |= local_cfg; 356839c8044fSJun Yang 356939c8044fSJun Yang return 0; 357039c8044fSJun Yang } 357139c8044fSJun Yang 357239c8044fSJun Yang static int 3573a8a6b82eSJun Yang dpaa2_configure_flow_ecpri(struct dpaa2_dev_flow *flow, 3574a8a6b82eSJun Yang struct rte_eth_dev *dev, 3575a8a6b82eSJun Yang const struct rte_flow_attr *attr, 3576a8a6b82eSJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 3577a8a6b82eSJun Yang const struct rte_flow_action actions[] __rte_unused, 3578a8a6b82eSJun Yang struct rte_flow_error *error __rte_unused, 3579a8a6b82eSJun Yang int *device_configured) 3580a8a6b82eSJun Yang { 3581a8a6b82eSJun Yang int ret, local_cfg = 0; 3582a8a6b82eSJun Yang uint32_t group; 3583a8a6b82eSJun Yang const struct rte_flow_item_ecpri *spec, *mask; 3584a8a6b82eSJun Yang struct rte_flow_item_ecpri local_mask; 3585a8a6b82eSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 3586a8a6b82eSJun Yang const struct rte_flow_item *pattern = 3587a8a6b82eSJun Yang &dpaa2_pattern->generic_item; 3588a8a6b82eSJun Yang uint8_t extract_nb = 0, i; 3589a8a6b82eSJun Yang uint64_t rule_data[DPAA2_ECPRI_MAX_EXTRACT_NB]; 3590a8a6b82eSJun Yang uint64_t mask_data[DPAA2_ECPRI_MAX_EXTRACT_NB]; 3591a8a6b82eSJun Yang uint8_t extract_size[DPAA2_ECPRI_MAX_EXTRACT_NB]; 3592a8a6b82eSJun Yang uint8_t extract_off[DPAA2_ECPRI_MAX_EXTRACT_NB]; 3593a8a6b82eSJun Yang 3594a8a6b82eSJun Yang group = attr->group; 3595a8a6b82eSJun Yang 3596a8a6b82eSJun Yang /* Parse pattern list to get the matching parameters */ 3597a8a6b82eSJun Yang spec = pattern->spec; 3598a8a6b82eSJun Yang if (pattern->mask) { 3599a8a6b82eSJun Yang memcpy(&local_mask, pattern->mask, 3600a8a6b82eSJun Yang sizeof(struct rte_flow_item_ecpri)); 3601a8a6b82eSJun Yang local_mask.hdr.common.u32 = 3602a8a6b82eSJun Yang rte_be_to_cpu_32(local_mask.hdr.common.u32); 3603a8a6b82eSJun Yang mask = &local_mask; 3604a8a6b82eSJun Yang } else { 3605a8a6b82eSJun Yang mask = &dpaa2_flow_item_ecpri_mask; 3606a8a6b82eSJun Yang } 3607a8a6b82eSJun Yang 3608a8a6b82eSJun Yang /* Get traffic class index and flow id to be configured */ 3609a8a6b82eSJun Yang flow->tc_id = group; 3610a8a6b82eSJun Yang flow->tc_index = attr->priority; 3611a8a6b82eSJun Yang 3612a8a6b82eSJun Yang if (dpaa2_pattern->in_tunnel) { 3613a8a6b82eSJun Yang DPAA2_PMD_ERR("Tunnel-ECPRI distribution not support"); 3614a8a6b82eSJun Yang return -ENOTSUP; 3615a8a6b82eSJun Yang } 3616a8a6b82eSJun Yang 3617a8a6b82eSJun Yang if (!spec) { 3618a8a6b82eSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3619a8a6b82eSJun Yang FAFE_ECPRI_FRAM, DPAA2_FLOW_QOS_TYPE, 3620a8a6b82eSJun Yang group, &local_cfg); 3621a8a6b82eSJun Yang if (ret) 3622a8a6b82eSJun Yang return ret; 3623a8a6b82eSJun Yang 3624a8a6b82eSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3625a8a6b82eSJun Yang FAFE_ECPRI_FRAM, DPAA2_FLOW_FS_TYPE, 3626a8a6b82eSJun Yang group, &local_cfg); 3627a8a6b82eSJun Yang if (ret) 3628a8a6b82eSJun Yang return ret; 3629a8a6b82eSJun Yang 3630a8a6b82eSJun Yang (*device_configured) |= local_cfg; 3631a8a6b82eSJun Yang return 0; 3632a8a6b82eSJun Yang } 3633a8a6b82eSJun Yang 36344cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 36354cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_ECPRI); 36364cc5cf4aSJun Yang if (ret) { 3637a8a6b82eSJun Yang DPAA2_PMD_WARN("Extract field(s) of ECPRI not support."); 3638a8a6b82eSJun Yang 36394cc5cf4aSJun Yang return ret; 3640a8a6b82eSJun Yang } 3641a8a6b82eSJun Yang 3642a8a6b82eSJun Yang if (mask->hdr.common.type != 0xff) { 3643a8a6b82eSJun Yang DPAA2_PMD_WARN("ECPRI header type not specified."); 3644a8a6b82eSJun Yang 36454cc5cf4aSJun Yang return -EINVAL; 3646a8a6b82eSJun Yang } 3647a8a6b82eSJun Yang 3648a8a6b82eSJun Yang if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_IQ_DATA) { 3649a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_0; 3650a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3651a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3652a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3653a8a6b82eSJun Yang extract_nb++; 3654a8a6b82eSJun Yang 3655a8a6b82eSJun Yang if (mask->hdr.type0.pc_id) { 3656a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type0.pc_id; 3657a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type0.pc_id; 3658a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3659a8a6b82eSJun Yang extract_off[extract_nb] = 3660a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3661a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_iq_data, pc_id); 3662a8a6b82eSJun Yang extract_nb++; 3663a8a6b82eSJun Yang } 3664a8a6b82eSJun Yang if (mask->hdr.type0.seq_id) { 3665a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type0.seq_id; 3666a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type0.seq_id; 3667a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3668a8a6b82eSJun Yang extract_off[extract_nb] = 3669a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3670a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_iq_data, seq_id); 3671a8a6b82eSJun Yang extract_nb++; 3672a8a6b82eSJun Yang } 3673a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_BIT_SEQ) { 3674a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_1; 3675a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3676a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3677a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3678a8a6b82eSJun Yang extract_nb++; 3679a8a6b82eSJun Yang 3680a8a6b82eSJun Yang if (mask->hdr.type1.pc_id) { 3681a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type1.pc_id; 3682a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type1.pc_id; 3683a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3684a8a6b82eSJun Yang extract_off[extract_nb] = 3685a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3686a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_bit_seq, pc_id); 3687a8a6b82eSJun Yang extract_nb++; 3688a8a6b82eSJun Yang } 3689a8a6b82eSJun Yang if (mask->hdr.type1.seq_id) { 3690a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type1.seq_id; 3691a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type1.seq_id; 3692a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3693a8a6b82eSJun Yang extract_off[extract_nb] = 3694a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3695a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_bit_seq, seq_id); 3696a8a6b82eSJun Yang extract_nb++; 3697a8a6b82eSJun Yang } 3698a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RTC_CTRL) { 3699a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_2; 3700a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3701a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3702a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3703a8a6b82eSJun Yang extract_nb++; 3704a8a6b82eSJun Yang 3705a8a6b82eSJun Yang if (mask->hdr.type2.rtc_id) { 3706a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type2.rtc_id; 3707a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type2.rtc_id; 3708a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3709a8a6b82eSJun Yang extract_off[extract_nb] = 3710a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3711a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_rtc_ctrl, rtc_id); 3712a8a6b82eSJun Yang extract_nb++; 3713a8a6b82eSJun Yang } 3714a8a6b82eSJun Yang if (mask->hdr.type2.seq_id) { 3715a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type2.seq_id; 3716a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type2.seq_id; 3717a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3718a8a6b82eSJun Yang extract_off[extract_nb] = 3719a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3720a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_rtc_ctrl, seq_id); 3721a8a6b82eSJun Yang extract_nb++; 3722a8a6b82eSJun Yang } 3723a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_GEN_DATA) { 3724a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_3; 3725a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3726a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3727a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3728a8a6b82eSJun Yang extract_nb++; 3729a8a6b82eSJun Yang 3730a8a6b82eSJun Yang if (mask->hdr.type3.pc_id || mask->hdr.type3.seq_id) 3731a8a6b82eSJun Yang DPAA2_PMD_WARN("Extract type3 msg not support."); 3732a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RM_ACC) { 3733a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_4; 3734a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3735a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3736a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3737a8a6b82eSJun Yang extract_nb++; 3738a8a6b82eSJun Yang 3739a8a6b82eSJun Yang if (mask->hdr.type4.rma_id) { 3740a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type4.rma_id; 3741a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type4.rma_id; 3742a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3743a8a6b82eSJun Yang extract_off[extract_nb] = 3744a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 0; 3745a8a6b82eSJun Yang /** Compiler not support to take address 3746a8a6b82eSJun Yang * of bit-field 3747a8a6b82eSJun Yang * offsetof(struct rte_ecpri_msg_rm_access, 3748a8a6b82eSJun Yang * rma_id); 3749a8a6b82eSJun Yang */ 3750a8a6b82eSJun Yang extract_nb++; 3751a8a6b82eSJun Yang } 3752a8a6b82eSJun Yang if (mask->hdr.type4.ele_id) { 3753a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type4.ele_id; 3754a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type4.ele_id; 3755a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3756a8a6b82eSJun Yang extract_off[extract_nb] = 3757a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 2; 3758a8a6b82eSJun Yang /** Compiler not support to take address 3759a8a6b82eSJun Yang * of bit-field 3760a8a6b82eSJun Yang * offsetof(struct rte_ecpri_msg_rm_access, 3761a8a6b82eSJun Yang * ele_id); 3762a8a6b82eSJun Yang */ 3763a8a6b82eSJun Yang extract_nb++; 3764a8a6b82eSJun Yang } 3765a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_DLY_MSR) { 3766a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_5; 3767a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3768a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3769a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3770a8a6b82eSJun Yang extract_nb++; 3771a8a6b82eSJun Yang 3772a8a6b82eSJun Yang if (mask->hdr.type5.msr_id) { 3773a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type5.msr_id; 3774a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type5.msr_id; 3775a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3776a8a6b82eSJun Yang extract_off[extract_nb] = 3777a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3778a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_delay_measure, 3779a8a6b82eSJun Yang msr_id); 3780a8a6b82eSJun Yang extract_nb++; 3781a8a6b82eSJun Yang } 3782a8a6b82eSJun Yang if (mask->hdr.type5.act_type) { 3783a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type5.act_type; 3784a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type5.act_type; 3785a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3786a8a6b82eSJun Yang extract_off[extract_nb] = 3787a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3788a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_delay_measure, 3789a8a6b82eSJun Yang act_type); 3790a8a6b82eSJun Yang extract_nb++; 3791a8a6b82eSJun Yang } 3792a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RMT_RST) { 3793a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_6; 3794a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3795a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3796a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3797a8a6b82eSJun Yang extract_nb++; 3798a8a6b82eSJun Yang 3799a8a6b82eSJun Yang if (mask->hdr.type6.rst_id) { 3800a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type6.rst_id; 3801a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type6.rst_id; 3802a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(rte_be16_t); 3803a8a6b82eSJun Yang extract_off[extract_nb] = 3804a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3805a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_remote_reset, 3806a8a6b82eSJun Yang rst_id); 3807a8a6b82eSJun Yang extract_nb++; 3808a8a6b82eSJun Yang } 3809a8a6b82eSJun Yang if (mask->hdr.type6.rst_op) { 3810a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type6.rst_op; 3811a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type6.rst_op; 3812a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3813a8a6b82eSJun Yang extract_off[extract_nb] = 3814a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3815a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_remote_reset, 3816a8a6b82eSJun Yang rst_op); 3817a8a6b82eSJun Yang extract_nb++; 3818a8a6b82eSJun Yang } 3819a8a6b82eSJun Yang } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_EVT_IND) { 3820a8a6b82eSJun Yang rule_data[extract_nb] = ECPRI_FAFE_TYPE_7; 3821a8a6b82eSJun Yang mask_data[extract_nb] = 0xff; 3822a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3823a8a6b82eSJun Yang extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET; 3824a8a6b82eSJun Yang extract_nb++; 3825a8a6b82eSJun Yang 3826a8a6b82eSJun Yang if (mask->hdr.type7.evt_id) { 3827a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type7.evt_id; 3828a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type7.evt_id; 3829a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3830a8a6b82eSJun Yang extract_off[extract_nb] = 3831a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3832a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_event_ind, 3833a8a6b82eSJun Yang evt_id); 3834a8a6b82eSJun Yang extract_nb++; 3835a8a6b82eSJun Yang } 3836a8a6b82eSJun Yang if (mask->hdr.type7.evt_type) { 3837a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type7.evt_type; 3838a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type7.evt_type; 3839a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3840a8a6b82eSJun Yang extract_off[extract_nb] = 3841a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3842a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_event_ind, 3843a8a6b82eSJun Yang evt_type); 3844a8a6b82eSJun Yang extract_nb++; 3845a8a6b82eSJun Yang } 3846a8a6b82eSJun Yang if (mask->hdr.type7.seq) { 3847a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type7.seq; 3848a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type7.seq; 3849a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3850a8a6b82eSJun Yang extract_off[extract_nb] = 3851a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3852a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_event_ind, 3853a8a6b82eSJun Yang seq); 3854a8a6b82eSJun Yang extract_nb++; 3855a8a6b82eSJun Yang } 3856a8a6b82eSJun Yang if (mask->hdr.type7.number) { 3857a8a6b82eSJun Yang rule_data[extract_nb] = spec->hdr.type7.number; 3858a8a6b82eSJun Yang mask_data[extract_nb] = mask->hdr.type7.number; 3859a8a6b82eSJun Yang extract_size[extract_nb] = sizeof(uint8_t); 3860a8a6b82eSJun Yang extract_off[extract_nb] = 3861a8a6b82eSJun Yang DPAA2_ECPRI_MSG_OFFSET + 3862a8a6b82eSJun Yang offsetof(struct rte_ecpri_msg_event_ind, 3863a8a6b82eSJun Yang number); 3864a8a6b82eSJun Yang extract_nb++; 3865a8a6b82eSJun Yang } 3866a8a6b82eSJun Yang } else { 3867a8a6b82eSJun Yang DPAA2_PMD_ERR("Invalid ecpri header type(%d)", 3868a8a6b82eSJun Yang spec->hdr.common.type); 3869a8a6b82eSJun Yang return -EINVAL; 3870a8a6b82eSJun Yang } 3871a8a6b82eSJun Yang 3872a8a6b82eSJun Yang for (i = 0; i < extract_nb; i++) { 3873a8a6b82eSJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 3874a8a6b82eSJun Yang extract_off[i], 3875a8a6b82eSJun Yang extract_size[i], &rule_data[i], &mask_data[i], 3876a8a6b82eSJun Yang priv, group, 3877a8a6b82eSJun Yang device_configured, 3878a8a6b82eSJun Yang DPAA2_FLOW_QOS_TYPE); 3879a8a6b82eSJun Yang if (ret) 3880a8a6b82eSJun Yang return ret; 3881a8a6b82eSJun Yang 3882a8a6b82eSJun Yang ret = dpaa2_flow_add_pr_extract_rule(flow, 3883a8a6b82eSJun Yang extract_off[i], 3884a8a6b82eSJun Yang extract_size[i], &rule_data[i], &mask_data[i], 3885a8a6b82eSJun Yang priv, group, 3886a8a6b82eSJun Yang device_configured, 3887a8a6b82eSJun Yang DPAA2_FLOW_FS_TYPE); 3888a8a6b82eSJun Yang if (ret) 3889a8a6b82eSJun Yang return ret; 3890a8a6b82eSJun Yang } 3891a8a6b82eSJun Yang 3892a8a6b82eSJun Yang (*device_configured) |= local_cfg; 3893a8a6b82eSJun Yang 3894a8a6b82eSJun Yang return 0; 3895a8a6b82eSJun Yang } 3896a8a6b82eSJun Yang 3897a8a6b82eSJun Yang static int 3898146c745eSJun Yang dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow, 3899146c745eSJun Yang struct rte_eth_dev *dev, 3900146c745eSJun Yang const struct rte_flow_attr *attr, 3901146c745eSJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 3902146c745eSJun Yang const struct rte_flow_action actions[] __rte_unused, 3903146c745eSJun Yang struct rte_flow_error *error __rte_unused, 3904146c745eSJun Yang int *device_configured) 3905146c745eSJun Yang { 3906146c745eSJun Yang int ret, local_cfg = 0; 3907146c745eSJun Yang uint32_t group; 3908146c745eSJun Yang const struct rte_flow_item_gtp *spec, *mask; 3909146c745eSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 3910146c745eSJun Yang const struct rte_flow_item *pattern = 3911146c745eSJun Yang &dpaa2_pattern->generic_item; 3912146c745eSJun Yang 3913146c745eSJun Yang group = attr->group; 3914146c745eSJun Yang 3915146c745eSJun Yang /* Parse pattern list to get the matching parameters */ 3916146c745eSJun Yang spec = pattern->spec; 3917146c745eSJun Yang mask = pattern->mask ? 3918146c745eSJun Yang pattern->mask : &dpaa2_flow_item_gtp_mask; 3919146c745eSJun Yang 3920146c745eSJun Yang /* Get traffic class index and flow id to be configured */ 3921146c745eSJun Yang flow->tc_id = group; 3922146c745eSJun Yang flow->tc_index = attr->priority; 3923146c745eSJun Yang 3924146c745eSJun Yang if (dpaa2_pattern->in_tunnel) { 3925146c745eSJun Yang DPAA2_PMD_ERR("Tunnel-GTP distribution not support"); 3926146c745eSJun Yang return -ENOTSUP; 3927146c745eSJun Yang } 3928146c745eSJun Yang 3929146c745eSJun Yang if (!spec) { 3930146c745eSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3931146c745eSJun Yang FAF_GTP_FRAM, DPAA2_FLOW_QOS_TYPE, 3932146c745eSJun Yang group, &local_cfg); 3933146c745eSJun Yang if (ret) 3934146c745eSJun Yang return ret; 3935146c745eSJun Yang 3936146c745eSJun Yang ret = dpaa2_flow_identify_by_faf(priv, flow, 3937146c745eSJun Yang FAF_GTP_FRAM, DPAA2_FLOW_FS_TYPE, 3938146c745eSJun Yang group, &local_cfg); 3939146c745eSJun Yang if (ret) 3940146c745eSJun Yang return ret; 3941146c745eSJun Yang 3942146c745eSJun Yang (*device_configured) |= local_cfg; 3943146c745eSJun Yang return 0; 3944146c745eSJun Yang } 3945146c745eSJun Yang 39464cc5cf4aSJun Yang ret = dpaa2_flow_extract_support((const uint8_t *)mask, 39474cc5cf4aSJun Yang RTE_FLOW_ITEM_TYPE_GTP); 39484cc5cf4aSJun Yang if (ret) { 3949146c745eSJun Yang DPAA2_PMD_WARN("Extract field(s) of GTP not support."); 3950146c745eSJun Yang 39514cc5cf4aSJun Yang return ret; 3952146c745eSJun Yang } 3953146c745eSJun Yang 3954146c745eSJun Yang if (!mask->teid) 3955146c745eSJun Yang return 0; 3956146c745eSJun Yang 3957146c745eSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP, 3958146c745eSJun Yang NH_FLD_GTP_TEID, &spec->teid, 3959146c745eSJun Yang &mask->teid, sizeof(rte_be32_t), 3960146c745eSJun Yang priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); 3961146c745eSJun Yang if (ret) 3962146c745eSJun Yang return ret; 3963146c745eSJun Yang 3964146c745eSJun Yang ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP, 3965146c745eSJun Yang NH_FLD_GTP_TEID, &spec->teid, 3966146c745eSJun Yang &mask->teid, sizeof(rte_be32_t), 3967146c745eSJun Yang priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); 3968146c745eSJun Yang if (ret) 3969146c745eSJun Yang return ret; 3970146c745eSJun Yang 3971146c745eSJun Yang (*device_configured) |= local_cfg; 3972146c745eSJun Yang 3973146c745eSJun Yang return 0; 3974146c745eSJun Yang } 3975146c745eSJun Yang 3976146c745eSJun Yang static int 397756c1817dSJun Yang dpaa2_configure_flow_raw(struct dpaa2_dev_flow *flow, 39783f881f8dSNipun Gupta struct rte_eth_dev *dev, 39793f881f8dSNipun Gupta const struct rte_flow_attr *attr, 39809ec29343SJun Yang const struct rte_dpaa2_flow_item *dpaa2_pattern, 39813f881f8dSNipun Gupta const struct rte_flow_action actions[] __rte_unused, 39823f881f8dSNipun Gupta struct rte_flow_error *error __rte_unused, 39833f881f8dSNipun Gupta int *device_configured) 39843f881f8dSNipun Gupta { 39853f881f8dSNipun Gupta struct dpaa2_dev_priv *priv = dev->data->dev_private; 39863f881f8dSNipun Gupta int local_cfg = 0, ret; 39873f881f8dSNipun Gupta uint32_t group; 3988e21bff64SJun Yang struct dpaa2_key_extract *qos_key_extract; 3989e21bff64SJun Yang struct dpaa2_key_extract *tc_key_extract; 39909ec29343SJun Yang const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item; 39919ec29343SJun Yang const struct rte_flow_item_raw *spec = pattern->spec; 39929ec29343SJun Yang const struct rte_flow_item_raw *mask = pattern->mask; 39933f881f8dSNipun Gupta 39943f881f8dSNipun Gupta /* Need both spec and mask */ 39953f881f8dSNipun Gupta if (!spec || !mask) { 39963f881f8dSNipun Gupta DPAA2_PMD_ERR("spec or mask not present."); 39973f881f8dSNipun Gupta return -EINVAL; 39983f881f8dSNipun Gupta } 3999e21bff64SJun Yang 4000e21bff64SJun Yang if (spec->relative) { 4001e21bff64SJun Yang /* TBD: relative offset support. 4002e21bff64SJun Yang * To support relative offset of previous L3 protocol item, 4003e21bff64SJun Yang * extracts should be expanded to identify if the frame is: 4004e21bff64SJun Yang * vlan or none-vlan. 4005e21bff64SJun Yang * 4006e21bff64SJun Yang * To support relative offset of previous L4 protocol item, 4007e21bff64SJun Yang * extracts should be expanded to identify if the frame is: 4008e21bff64SJun Yang * vlan/IPv4 or vlan/IPv6 or none-vlan/IPv4 or none-vlan/IPv6. 4009e21bff64SJun Yang */ 4010e21bff64SJun Yang DPAA2_PMD_ERR("relative not supported."); 40113f881f8dSNipun Gupta return -EINVAL; 40123f881f8dSNipun Gupta } 4013e21bff64SJun Yang 4014e21bff64SJun Yang if (spec->search) { 4015e21bff64SJun Yang DPAA2_PMD_ERR("search not supported."); 4016e21bff64SJun Yang return -EINVAL; 4017e21bff64SJun Yang } 4018e21bff64SJun Yang 40193f881f8dSNipun Gupta /* Spec len and mask len should be same */ 40203f881f8dSNipun Gupta if (spec->length != mask->length) { 40213f881f8dSNipun Gupta DPAA2_PMD_ERR("Spec len and mask len mismatch."); 40223f881f8dSNipun Gupta return -EINVAL; 40233f881f8dSNipun Gupta } 40243f881f8dSNipun Gupta 40253f881f8dSNipun Gupta /* Get traffic class index and flow id to be configured */ 40263f881f8dSNipun Gupta group = attr->group; 40273f881f8dSNipun Gupta flow->tc_id = group; 40283f881f8dSNipun Gupta flow->tc_index = attr->priority; 40293f881f8dSNipun Gupta 4030e21bff64SJun Yang qos_key_extract = &priv->extract.qos_key_extract; 4031e21bff64SJun Yang tc_key_extract = &priv->extract.tc_key_extract[group]; 4032e21bff64SJun Yang 4033e21bff64SJun Yang ret = dpaa2_flow_extract_add_raw(priv, 4034e21bff64SJun Yang spec->offset, spec->length, 4035e21bff64SJun Yang DPAA2_FLOW_QOS_TYPE, 0, &local_cfg); 40363f881f8dSNipun Gupta if (ret) { 40373f881f8dSNipun Gupta DPAA2_PMD_ERR("QoS Extract RAW add failed."); 4038e21bff64SJun Yang return -EINVAL; 40393f881f8dSNipun Gupta } 40403f881f8dSNipun Gupta 4041e21bff64SJun Yang ret = dpaa2_flow_extract_add_raw(priv, 4042e21bff64SJun Yang spec->offset, spec->length, 4043e21bff64SJun Yang DPAA2_FLOW_FS_TYPE, group, &local_cfg); 40443f881f8dSNipun Gupta if (ret) { 4045e21bff64SJun Yang DPAA2_PMD_ERR("FS[%d] Extract RAW add failed.", 4046e21bff64SJun Yang group); 4047e21bff64SJun Yang return -EINVAL; 40483f881f8dSNipun Gupta } 40493f881f8dSNipun Gupta 4050e21bff64SJun Yang ret = dpaa2_flow_raw_rule_data_set(flow, 4051e21bff64SJun Yang &qos_key_extract->key_profile, 4052e21bff64SJun Yang spec->offset, spec->length, 4053e21bff64SJun Yang spec->pattern, mask->pattern, 4054e21bff64SJun Yang DPAA2_FLOW_QOS_TYPE); 40553f881f8dSNipun Gupta if (ret) { 40563f881f8dSNipun Gupta DPAA2_PMD_ERR("QoS RAW rule data set failed"); 4057e21bff64SJun Yang return -EINVAL; 40583f881f8dSNipun Gupta } 40593f881f8dSNipun Gupta 4060e21bff64SJun Yang ret = dpaa2_flow_raw_rule_data_set(flow, 4061e21bff64SJun Yang &tc_key_extract->key_profile, 4062e21bff64SJun Yang spec->offset, spec->length, 4063e21bff64SJun Yang spec->pattern, mask->pattern, 4064e21bff64SJun Yang DPAA2_FLOW_FS_TYPE); 40653f881f8dSNipun Gupta if (ret) { 40663f881f8dSNipun Gupta DPAA2_PMD_ERR("FS RAW rule data set failed"); 4067e21bff64SJun Yang return -EINVAL; 40683f881f8dSNipun Gupta } 40693f881f8dSNipun Gupta 40703f881f8dSNipun Gupta (*device_configured) |= local_cfg; 40713f881f8dSNipun Gupta 40723f881f8dSNipun Gupta return 0; 40733f881f8dSNipun Gupta } 40743f881f8dSNipun Gupta 4075028d1dfdSJun Yang static inline int 407656c1817dSJun Yang dpaa2_flow_verify_attr(struct dpaa2_dev_priv *priv, 40774ce58f8aSJun Yang const struct rte_flow_attr *attr) 40784ce58f8aSJun Yang { 407956c1817dSJun Yang struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows); 40804ce58f8aSJun Yang 40814ce58f8aSJun Yang while (curr) { 40824ce58f8aSJun Yang if (curr->tc_id == attr->group && 40834ce58f8aSJun Yang curr->tc_index == attr->priority) { 408456c1817dSJun Yang DPAA2_PMD_ERR("Flow(TC[%d].entry[%d] exists", 40854ce58f8aSJun Yang attr->group, attr->priority); 40864ce58f8aSJun Yang 408756c1817dSJun Yang return -EINVAL; 40884ce58f8aSJun Yang } 40894ce58f8aSJun Yang curr = LIST_NEXT(curr, next); 40904ce58f8aSJun Yang } 40914ce58f8aSJun Yang 40924ce58f8aSJun Yang return 0; 40934ce58f8aSJun Yang } 40944ce58f8aSJun Yang 4095028d1dfdSJun Yang static inline struct rte_eth_dev * 4096028d1dfdSJun Yang dpaa2_flow_redirect_dev(struct dpaa2_dev_priv *priv, 4097028d1dfdSJun Yang const struct rte_flow_action *action) 4098028d1dfdSJun Yang { 4099028d1dfdSJun Yang const struct rte_flow_action_port_id *port_id; 410056c1817dSJun Yang const struct rte_flow_action_ethdev *ethdev; 4101028d1dfdSJun Yang int idx = -1; 4102028d1dfdSJun Yang struct rte_eth_dev *dest_dev; 4103028d1dfdSJun Yang 4104235558feSIvan Malov if (action->type == RTE_FLOW_ACTION_TYPE_PORT_ID) { 410556c1817dSJun Yang port_id = action->conf; 4106028d1dfdSJun Yang if (!port_id->original) 4107028d1dfdSJun Yang idx = port_id->id; 4108b1e15294SIvan Malov } else if (action->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) { 410956c1817dSJun Yang ethdev = action->conf; 4110b1e15294SIvan Malov idx = ethdev->port_id; 4111028d1dfdSJun Yang } else { 4112028d1dfdSJun Yang return NULL; 4113028d1dfdSJun Yang } 4114028d1dfdSJun Yang 4115028d1dfdSJun Yang if (idx >= 0) { 4116028d1dfdSJun Yang if (!rte_eth_dev_is_valid_port(idx)) 4117028d1dfdSJun Yang return NULL; 411872cd5a48SJun Yang if (!rte_pmd_dpaa2_dev_is_dpaa2(idx)) 411972cd5a48SJun Yang return NULL; 4120028d1dfdSJun Yang dest_dev = &rte_eth_devices[idx]; 4121028d1dfdSJun Yang } else { 4122028d1dfdSJun Yang dest_dev = priv->eth_dev; 4123028d1dfdSJun Yang } 4124028d1dfdSJun Yang 4125028d1dfdSJun Yang return dest_dev; 4126028d1dfdSJun Yang } 4127028d1dfdSJun Yang 4128bac4a296SJun Yang static inline int 412956c1817dSJun Yang dpaa2_flow_verify_action(struct dpaa2_dev_priv *priv, 4130bac4a296SJun Yang const struct rte_flow_attr *attr, 4131bac4a296SJun Yang const struct rte_flow_action actions[]) 4132bac4a296SJun Yang { 4133bac4a296SJun Yang int end_of_list = 0, i, j = 0; 4134bac4a296SJun Yang const struct rte_flow_action_queue *dest_queue; 4135bac4a296SJun Yang const struct rte_flow_action_rss *rss_conf; 4136bac4a296SJun Yang struct dpaa2_queue *rxq; 4137bac4a296SJun Yang 4138bac4a296SJun Yang while (!end_of_list) { 4139bac4a296SJun Yang switch (actions[j].type) { 4140bac4a296SJun Yang case RTE_FLOW_ACTION_TYPE_QUEUE: 414156c1817dSJun Yang dest_queue = actions[j].conf; 4142bac4a296SJun Yang rxq = priv->rx_vq[dest_queue->index]; 4143bac4a296SJun Yang if (attr->group != rxq->tc_index) { 414456c1817dSJun Yang DPAA2_PMD_ERR("FSQ(%d.%d) not in TC[%d]", 414556c1817dSJun Yang rxq->tc_index, rxq->flow_id, 414656c1817dSJun Yang attr->group); 4147bac4a296SJun Yang 414856c1817dSJun Yang return -ENOTSUP; 4149bac4a296SJun Yang } 4150bac4a296SJun Yang break; 4151b1e15294SIvan Malov case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 4152028d1dfdSJun Yang case RTE_FLOW_ACTION_TYPE_PORT_ID: 4153028d1dfdSJun Yang if (!dpaa2_flow_redirect_dev(priv, &actions[j])) { 4154028d1dfdSJun Yang DPAA2_PMD_ERR("Invalid port id of action"); 4155028d1dfdSJun Yang return -ENOTSUP; 4156028d1dfdSJun Yang } 4157028d1dfdSJun Yang break; 4158bac4a296SJun Yang case RTE_FLOW_ACTION_TYPE_RSS: 4159bac4a296SJun Yang rss_conf = (const struct rte_flow_action_rss *) 4160bac4a296SJun Yang (actions[j].conf); 4161bac4a296SJun Yang if (rss_conf->queue_num > priv->dist_queues) { 416256c1817dSJun Yang DPAA2_PMD_ERR("RSS number too large"); 4163bac4a296SJun Yang return -ENOTSUP; 4164bac4a296SJun Yang } 4165bac4a296SJun Yang for (i = 0; i < (int)rss_conf->queue_num; i++) { 4166bac4a296SJun Yang if (rss_conf->queue[i] >= priv->nb_rx_queues) { 416756c1817dSJun Yang DPAA2_PMD_ERR("RSS queue not in range"); 4168bac4a296SJun Yang return -ENOTSUP; 4169bac4a296SJun Yang } 4170bac4a296SJun Yang rxq = priv->rx_vq[rss_conf->queue[i]]; 4171bac4a296SJun Yang if (rxq->tc_index != attr->group) { 417256c1817dSJun Yang DPAA2_PMD_ERR("RSS queue not in group"); 4173bac4a296SJun Yang return -ENOTSUP; 4174bac4a296SJun Yang } 4175bac4a296SJun Yang } 4176bac4a296SJun Yang 4177bac4a296SJun Yang break; 417839c8044fSJun Yang case RTE_FLOW_ACTION_TYPE_PF: 417939c8044fSJun Yang /* Skip this action, have to add for vxlan */ 418039c8044fSJun Yang break; 4181bac4a296SJun Yang case RTE_FLOW_ACTION_TYPE_END: 4182bac4a296SJun Yang end_of_list = 1; 4183bac4a296SJun Yang break; 4184bac4a296SJun Yang default: 4185bac4a296SJun Yang DPAA2_PMD_ERR("Invalid action type"); 4186bac4a296SJun Yang return -ENOTSUP; 4187bac4a296SJun Yang } 4188bac4a296SJun Yang j++; 4189bac4a296SJun Yang } 4190bac4a296SJun Yang 4191bac4a296SJun Yang return 0; 4192bac4a296SJun Yang } 4193bac4a296SJun Yang 4194fe2b986aSSunil Kumar Kori static int 419556c1817dSJun Yang dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv, 419656c1817dSJun Yang struct dpaa2_dev_flow *flow, 419756c1817dSJun Yang const struct rte_flow_action *rte_action) 419856c1817dSJun Yang { 419956c1817dSJun Yang struct rte_eth_dev *dest_dev; 420056c1817dSJun Yang struct dpaa2_dev_priv *dest_priv; 420156c1817dSJun Yang const struct rte_flow_action_queue *dest_queue; 420256c1817dSJun Yang struct dpaa2_queue *dest_q; 420356c1817dSJun Yang 420456c1817dSJun Yang memset(&flow->fs_action_cfg, 0, 420556c1817dSJun Yang sizeof(struct dpni_fs_action_cfg)); 420656c1817dSJun Yang flow->action_type = rte_action->type; 420756c1817dSJun Yang 420856c1817dSJun Yang if (flow->action_type == RTE_FLOW_ACTION_TYPE_QUEUE) { 420956c1817dSJun Yang dest_queue = rte_action->conf; 421056c1817dSJun Yang dest_q = priv->rx_vq[dest_queue->index]; 421156c1817dSJun Yang flow->fs_action_cfg.flow_id = dest_q->flow_id; 421256c1817dSJun Yang } else if (flow->action_type == RTE_FLOW_ACTION_TYPE_PORT_ID || 421356c1817dSJun Yang flow->action_type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) { 421456c1817dSJun Yang dest_dev = dpaa2_flow_redirect_dev(priv, rte_action); 421556c1817dSJun Yang if (!dest_dev) { 421656c1817dSJun Yang DPAA2_PMD_ERR("Invalid device to redirect"); 421756c1817dSJun Yang return -EINVAL; 421856c1817dSJun Yang } 421956c1817dSJun Yang 422056c1817dSJun Yang dest_priv = dest_dev->data->dev_private; 422156c1817dSJun Yang dest_q = dest_priv->tx_vq[0]; 422256c1817dSJun Yang flow->fs_action_cfg.options = 422356c1817dSJun Yang DPNI_FS_OPT_REDIRECT_TO_DPNI_TX; 422456c1817dSJun Yang flow->fs_action_cfg.redirect_obj_token = 422556c1817dSJun Yang dest_priv->token; 422656c1817dSJun Yang flow->fs_action_cfg.flow_id = dest_q->flow_id; 422756c1817dSJun Yang } 422856c1817dSJun Yang 422956c1817dSJun Yang return 0; 423056c1817dSJun Yang } 423156c1817dSJun Yang 423256c1817dSJun Yang static inline uint16_t 423356c1817dSJun Yang dpaa2_flow_entry_size(uint16_t key_max_size) 423456c1817dSJun Yang { 423556c1817dSJun Yang if (key_max_size > DPAA2_FLOW_ENTRY_MAX_SIZE) { 423656c1817dSJun Yang DPAA2_PMD_ERR("Key size(%d) > max(%d)", 423756c1817dSJun Yang key_max_size, 423856c1817dSJun Yang DPAA2_FLOW_ENTRY_MAX_SIZE); 423956c1817dSJun Yang 424056c1817dSJun Yang return 0; 424156c1817dSJun Yang } 424256c1817dSJun Yang 424356c1817dSJun Yang if (key_max_size > DPAA2_FLOW_ENTRY_MIN_SIZE) 424456c1817dSJun Yang return DPAA2_FLOW_ENTRY_MAX_SIZE; 424556c1817dSJun Yang 424656c1817dSJun Yang /* Current MC only support fixed entry size(56)*/ 424756c1817dSJun Yang return DPAA2_FLOW_ENTRY_MAX_SIZE; 424856c1817dSJun Yang } 424956c1817dSJun Yang 425056c1817dSJun Yang static inline int 425156c1817dSJun Yang dpaa2_flow_clear_fs_table(struct dpaa2_dev_priv *priv, 425256c1817dSJun Yang uint8_t tc_id) 425356c1817dSJun Yang { 425456c1817dSJun Yang struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows); 425556c1817dSJun Yang int need_clear = 0, ret; 425656c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 425756c1817dSJun Yang 425856c1817dSJun Yang while (curr) { 425956c1817dSJun Yang if (curr->tc_id == tc_id) { 426056c1817dSJun Yang need_clear = 1; 426156c1817dSJun Yang break; 426256c1817dSJun Yang } 426356c1817dSJun Yang curr = LIST_NEXT(curr, next); 426456c1817dSJun Yang } 426556c1817dSJun Yang 426656c1817dSJun Yang if (need_clear) { 426756c1817dSJun Yang ret = dpni_clear_fs_entries(dpni, CMD_PRI_LOW, 426856c1817dSJun Yang priv->token, tc_id); 426956c1817dSJun Yang if (ret) { 427056c1817dSJun Yang DPAA2_PMD_ERR("TC[%d] clear failed", tc_id); 427156c1817dSJun Yang return ret; 427256c1817dSJun Yang } 427356c1817dSJun Yang } 427456c1817dSJun Yang 427556c1817dSJun Yang return 0; 427656c1817dSJun Yang } 427756c1817dSJun Yang 427856c1817dSJun Yang static int 427956c1817dSJun Yang dpaa2_configure_fs_rss_table(struct dpaa2_dev_priv *priv, 428056c1817dSJun Yang uint8_t tc_id, uint16_t dist_size, int rss_dist) 428156c1817dSJun Yang { 428256c1817dSJun Yang struct dpaa2_key_extract *tc_extract; 428356c1817dSJun Yang uint8_t *key_cfg_buf; 428456c1817dSJun Yang uint64_t key_cfg_iova; 428556c1817dSJun Yang int ret; 428656c1817dSJun Yang struct dpni_rx_dist_cfg tc_cfg; 428756c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 428856c1817dSJun Yang uint16_t entry_size; 428956c1817dSJun Yang uint16_t key_max_size; 429056c1817dSJun Yang 429156c1817dSJun Yang ret = dpaa2_flow_clear_fs_table(priv, tc_id); 429256c1817dSJun Yang if (ret < 0) { 429356c1817dSJun Yang DPAA2_PMD_ERR("TC[%d] clear failed", tc_id); 429456c1817dSJun Yang return ret; 429556c1817dSJun Yang } 429656c1817dSJun Yang 429756c1817dSJun Yang tc_extract = &priv->extract.tc_key_extract[tc_id]; 429856c1817dSJun Yang key_cfg_buf = priv->extract.tc_extract_param[tc_id]; 429925d0ae62SJun Yang key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf, 430025d0ae62SJun Yang DPAA2_EXTRACT_PARAM_MAX_SIZE); 430125d0ae62SJun Yang if (key_cfg_iova == RTE_BAD_IOVA) { 430225d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)", 430325d0ae62SJun Yang __func__, key_cfg_buf); 430425d0ae62SJun Yang 430525d0ae62SJun Yang return -ENOBUFS; 430625d0ae62SJun Yang } 430756c1817dSJun Yang 430856c1817dSJun Yang key_max_size = tc_extract->key_profile.key_max_size; 430956c1817dSJun Yang entry_size = dpaa2_flow_entry_size(key_max_size); 431056c1817dSJun Yang 431156c1817dSJun Yang dpaa2_flow_fs_extracts_log(priv, tc_id); 431256c1817dSJun Yang ret = dpkg_prepare_key_cfg(&tc_extract->dpkg, 431356c1817dSJun Yang key_cfg_buf); 431456c1817dSJun Yang if (ret < 0) { 431556c1817dSJun Yang DPAA2_PMD_ERR("TC[%d] prepare key failed", tc_id); 431656c1817dSJun Yang return ret; 431756c1817dSJun Yang } 431856c1817dSJun Yang 431956c1817dSJun Yang memset(&tc_cfg, 0, sizeof(struct dpni_rx_dist_cfg)); 432056c1817dSJun Yang tc_cfg.dist_size = dist_size; 432156c1817dSJun Yang tc_cfg.key_cfg_iova = key_cfg_iova; 432256c1817dSJun Yang if (rss_dist) 432356c1817dSJun Yang tc_cfg.enable = true; 432456c1817dSJun Yang else 432556c1817dSJun Yang tc_cfg.enable = false; 432656c1817dSJun Yang tc_cfg.tc = tc_id; 432756c1817dSJun Yang ret = dpni_set_rx_hash_dist(dpni, CMD_PRI_LOW, 432856c1817dSJun Yang priv->token, &tc_cfg); 432956c1817dSJun Yang if (ret < 0) { 433056c1817dSJun Yang if (rss_dist) { 433156c1817dSJun Yang DPAA2_PMD_ERR("RSS TC[%d] set failed", 433256c1817dSJun Yang tc_id); 433356c1817dSJun Yang } else { 433456c1817dSJun Yang DPAA2_PMD_ERR("FS TC[%d] hash disable failed", 433556c1817dSJun Yang tc_id); 433656c1817dSJun Yang } 433756c1817dSJun Yang 433856c1817dSJun Yang return ret; 433956c1817dSJun Yang } 434056c1817dSJun Yang 434156c1817dSJun Yang if (rss_dist) 434256c1817dSJun Yang return 0; 434356c1817dSJun Yang 434456c1817dSJun Yang tc_cfg.enable = true; 434556c1817dSJun Yang tc_cfg.fs_miss_flow_id = dpaa2_flow_miss_flow_id; 434656c1817dSJun Yang ret = dpni_set_rx_fs_dist(dpni, CMD_PRI_LOW, 434756c1817dSJun Yang priv->token, &tc_cfg); 434856c1817dSJun Yang if (ret < 0) { 434956c1817dSJun Yang DPAA2_PMD_ERR("TC[%d] FS configured failed", tc_id); 435056c1817dSJun Yang return ret; 435156c1817dSJun Yang } 435256c1817dSJun Yang 435356c1817dSJun Yang ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_FS_TYPE, 435456c1817dSJun Yang entry_size, tc_id); 435556c1817dSJun Yang if (ret) 435656c1817dSJun Yang return ret; 435756c1817dSJun Yang 435856c1817dSJun Yang return 0; 435956c1817dSJun Yang } 436056c1817dSJun Yang 436156c1817dSJun Yang static int 436256c1817dSJun Yang dpaa2_configure_qos_table(struct dpaa2_dev_priv *priv, 436356c1817dSJun Yang int rss_dist) 436456c1817dSJun Yang { 436556c1817dSJun Yang struct dpaa2_key_extract *qos_extract; 436656c1817dSJun Yang uint8_t *key_cfg_buf; 436756c1817dSJun Yang uint64_t key_cfg_iova; 436856c1817dSJun Yang int ret; 436956c1817dSJun Yang struct dpni_qos_tbl_cfg qos_cfg; 437056c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 437156c1817dSJun Yang uint16_t entry_size; 437256c1817dSJun Yang uint16_t key_max_size; 437356c1817dSJun Yang 437456c1817dSJun Yang if (!rss_dist && priv->num_rx_tc <= 1) { 437556c1817dSJun Yang /* QoS table is effecitive for FS multiple TCs or RSS.*/ 437656c1817dSJun Yang return 0; 437756c1817dSJun Yang } 437856c1817dSJun Yang 437956c1817dSJun Yang if (LIST_FIRST(&priv->flows)) { 438056c1817dSJun Yang ret = dpni_clear_qos_table(dpni, CMD_PRI_LOW, 438156c1817dSJun Yang priv->token); 438256c1817dSJun Yang if (ret < 0) { 438356c1817dSJun Yang DPAA2_PMD_ERR("QoS table clear failed"); 438456c1817dSJun Yang return ret; 438556c1817dSJun Yang } 438656c1817dSJun Yang } 438756c1817dSJun Yang 438856c1817dSJun Yang qos_extract = &priv->extract.qos_key_extract; 438956c1817dSJun Yang key_cfg_buf = priv->extract.qos_extract_param; 439025d0ae62SJun Yang key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf, 439125d0ae62SJun Yang DPAA2_EXTRACT_PARAM_MAX_SIZE); 439225d0ae62SJun Yang if (key_cfg_iova == RTE_BAD_IOVA) { 439325d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)", 439425d0ae62SJun Yang __func__, key_cfg_buf); 439525d0ae62SJun Yang 439625d0ae62SJun Yang return -ENOBUFS; 439725d0ae62SJun Yang } 439856c1817dSJun Yang 439956c1817dSJun Yang key_max_size = qos_extract->key_profile.key_max_size; 440056c1817dSJun Yang entry_size = dpaa2_flow_entry_size(key_max_size); 440156c1817dSJun Yang 440256c1817dSJun Yang dpaa2_flow_qos_extracts_log(priv); 440356c1817dSJun Yang 440456c1817dSJun Yang ret = dpkg_prepare_key_cfg(&qos_extract->dpkg, 440556c1817dSJun Yang key_cfg_buf); 440656c1817dSJun Yang if (ret < 0) { 440756c1817dSJun Yang DPAA2_PMD_ERR("QoS prepare extract failed"); 440856c1817dSJun Yang return ret; 440956c1817dSJun Yang } 441056c1817dSJun Yang memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg)); 441156c1817dSJun Yang qos_cfg.keep_entries = true; 441256c1817dSJun Yang qos_cfg.key_cfg_iova = key_cfg_iova; 441356c1817dSJun Yang if (rss_dist) { 441456c1817dSJun Yang qos_cfg.discard_on_miss = true; 441556c1817dSJun Yang } else { 441656c1817dSJun Yang qos_cfg.discard_on_miss = false; 441756c1817dSJun Yang qos_cfg.default_tc = 0; 441856c1817dSJun Yang } 441956c1817dSJun Yang 442056c1817dSJun Yang ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, 442156c1817dSJun Yang priv->token, &qos_cfg); 442256c1817dSJun Yang if (ret < 0) { 442356c1817dSJun Yang DPAA2_PMD_ERR("QoS table set failed"); 442456c1817dSJun Yang return ret; 442556c1817dSJun Yang } 442656c1817dSJun Yang 442756c1817dSJun Yang ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_QOS_TYPE, 442856c1817dSJun Yang entry_size, 0); 442956c1817dSJun Yang if (ret) 443056c1817dSJun Yang return ret; 443156c1817dSJun Yang 443256c1817dSJun Yang return 0; 443356c1817dSJun Yang } 443456c1817dSJun Yang 443556c1817dSJun Yang static int 44369ec29343SJun Yang dpaa2_flow_item_convert(const struct rte_flow_item pattern[], 44379ec29343SJun Yang struct rte_dpaa2_flow_item **dpaa2_pattern) 44389ec29343SJun Yang { 44399ec29343SJun Yang struct rte_dpaa2_flow_item *new_pattern; 44409ec29343SJun Yang int num = 0, tunnel_start = 0; 44419ec29343SJun Yang 44429ec29343SJun Yang while (1) { 44439ec29343SJun Yang num++; 44449ec29343SJun Yang if (pattern[num].type == RTE_FLOW_ITEM_TYPE_END) 44459ec29343SJun Yang break; 44469ec29343SJun Yang } 44479ec29343SJun Yang 44489ec29343SJun Yang new_pattern = rte_malloc(NULL, sizeof(struct rte_dpaa2_flow_item) * num, 44499ec29343SJun Yang RTE_CACHE_LINE_SIZE); 44509ec29343SJun Yang if (!new_pattern) { 44519ec29343SJun Yang DPAA2_PMD_ERR("Failed to alloc %d flow items", num); 44529ec29343SJun Yang return -ENOMEM; 44539ec29343SJun Yang } 44549ec29343SJun Yang 44559ec29343SJun Yang num = 0; 44569ec29343SJun Yang while (pattern[num].type != RTE_FLOW_ITEM_TYPE_END) { 44579ec29343SJun Yang memcpy(&new_pattern[num].generic_item, &pattern[num], 44589ec29343SJun Yang sizeof(struct rte_flow_item)); 44599ec29343SJun Yang new_pattern[num].in_tunnel = 0; 44609ec29343SJun Yang 44619ec29343SJun Yang if (pattern[num].type == RTE_FLOW_ITEM_TYPE_VXLAN) 44629ec29343SJun Yang tunnel_start = 1; 44639ec29343SJun Yang else if (tunnel_start) 44649ec29343SJun Yang new_pattern[num].in_tunnel = 1; 44659ec29343SJun Yang num++; 44669ec29343SJun Yang } 44679ec29343SJun Yang 44689ec29343SJun Yang new_pattern[num].generic_item.type = RTE_FLOW_ITEM_TYPE_END; 44699ec29343SJun Yang *dpaa2_pattern = new_pattern; 44709ec29343SJun Yang 44719ec29343SJun Yang return 0; 44729ec29343SJun Yang } 44739ec29343SJun Yang 44749ec29343SJun Yang static int 447556c1817dSJun Yang dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow, 4476fe2b986aSSunil Kumar Kori struct rte_eth_dev *dev, 4477fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr, 4478fe2b986aSSunil Kumar Kori const struct rte_flow_item pattern[], 4479fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[], 4480fe2b986aSSunil Kumar Kori struct rte_flow_error *error) 4481fe2b986aSSunil Kumar Kori { 4482fe2b986aSSunil Kumar Kori const struct rte_flow_action_rss *rss_conf; 4483fe2b986aSSunil Kumar Kori int is_keycfg_configured = 0, end_of_list = 0; 4484fe2b986aSSunil Kumar Kori int ret = 0, i = 0, j = 0; 4485fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 448656c1817dSJun Yang struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows); 448756c1817dSJun Yang uint16_t dist_size, key_size; 448856c1817dSJun Yang struct dpaa2_key_extract *qos_key_extract; 448956c1817dSJun Yang struct dpaa2_key_extract *tc_key_extract; 44909ec29343SJun Yang struct rte_dpaa2_flow_item *dpaa2_pattern = NULL; 44914ce58f8aSJun Yang 44924ce58f8aSJun Yang ret = dpaa2_flow_verify_attr(priv, attr); 44934ce58f8aSJun Yang if (ret) 44944ce58f8aSJun Yang return ret; 4495fe2b986aSSunil Kumar Kori 4496bac4a296SJun Yang ret = dpaa2_flow_verify_action(priv, attr, actions); 4497bac4a296SJun Yang if (ret) 4498bac4a296SJun Yang return ret; 4499bac4a296SJun Yang 45009ec29343SJun Yang ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern); 45019ec29343SJun Yang if (ret) 45029ec29343SJun Yang return ret; 45039ec29343SJun Yang 4504fe2b986aSSunil Kumar Kori /* Parse pattern list to get the matching parameters */ 4505fe2b986aSSunil Kumar Kori while (!end_of_list) { 4506fe2b986aSSunil Kumar Kori switch (pattern[i].type) { 4507fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_ETH: 45089ec29343SJun Yang ret = dpaa2_configure_flow_eth(flow, dev, attr, 45099ec29343SJun Yang &dpaa2_pattern[i], 45109ec29343SJun Yang actions, error, 45115f176728SJun Yang &is_keycfg_configured); 45125f176728SJun Yang if (ret) { 451356c1817dSJun Yang DPAA2_PMD_ERR("ETH flow config failed!"); 45149ec29343SJun Yang goto end_flow_set; 45155f176728SJun Yang } 4516fe2b986aSSunil Kumar Kori break; 4517fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_VLAN: 45189ec29343SJun Yang ret = dpaa2_configure_flow_vlan(flow, dev, attr, 45199ec29343SJun Yang &dpaa2_pattern[i], 45209ec29343SJun Yang actions, error, 45215f176728SJun Yang &is_keycfg_configured); 45225f176728SJun Yang if (ret) { 452356c1817dSJun Yang DPAA2_PMD_ERR("vLan flow config failed!"); 45249ec29343SJun Yang goto end_flow_set; 45255f176728SJun Yang } 4526fe2b986aSSunil Kumar Kori break; 4527fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_IPV4: 45289ec29343SJun Yang ret = dpaa2_configure_flow_ipv4(flow, dev, attr, 45299ec29343SJun Yang &dpaa2_pattern[i], 45309ec29343SJun Yang actions, error, 45315f176728SJun Yang &is_keycfg_configured); 45325f176728SJun Yang if (ret) { 453356c1817dSJun Yang DPAA2_PMD_ERR("IPV4 flow config failed!"); 45349ec29343SJun Yang goto end_flow_set; 453556c1817dSJun Yang } 453656c1817dSJun Yang break; 453756c1817dSJun Yang case RTE_FLOW_ITEM_TYPE_IPV6: 45389ec29343SJun Yang ret = dpaa2_configure_flow_ipv6(flow, dev, attr, 45399ec29343SJun Yang &dpaa2_pattern[i], 45409ec29343SJun Yang actions, error, 454156c1817dSJun Yang &is_keycfg_configured); 454256c1817dSJun Yang if (ret) { 454356c1817dSJun Yang DPAA2_PMD_ERR("IPV6 flow config failed!"); 45449ec29343SJun Yang goto end_flow_set; 45455f176728SJun Yang } 4546fe2b986aSSunil Kumar Kori break; 4547fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_ICMP: 45489ec29343SJun Yang ret = dpaa2_configure_flow_icmp(flow, dev, attr, 45499ec29343SJun Yang &dpaa2_pattern[i], 45509ec29343SJun Yang actions, error, 45515f176728SJun Yang &is_keycfg_configured); 45525f176728SJun Yang if (ret) { 455356c1817dSJun Yang DPAA2_PMD_ERR("ICMP flow config failed!"); 45549ec29343SJun Yang goto end_flow_set; 45555f176728SJun Yang } 4556fe2b986aSSunil Kumar Kori break; 4557fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_UDP: 45589ec29343SJun Yang ret = dpaa2_configure_flow_udp(flow, dev, attr, 45599ec29343SJun Yang &dpaa2_pattern[i], 45609ec29343SJun Yang actions, error, 45615f176728SJun Yang &is_keycfg_configured); 45625f176728SJun Yang if (ret) { 456356c1817dSJun Yang DPAA2_PMD_ERR("UDP flow config failed!"); 45649ec29343SJun Yang goto end_flow_set; 45655f176728SJun Yang } 4566fe2b986aSSunil Kumar Kori break; 4567fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_TCP: 45689ec29343SJun Yang ret = dpaa2_configure_flow_tcp(flow, dev, attr, 45699ec29343SJun Yang &dpaa2_pattern[i], 45709ec29343SJun Yang actions, error, 45715f176728SJun Yang &is_keycfg_configured); 45725f176728SJun Yang if (ret) { 457356c1817dSJun Yang DPAA2_PMD_ERR("TCP flow config failed!"); 45749ec29343SJun Yang goto end_flow_set; 45755f176728SJun Yang } 4576fe2b986aSSunil Kumar Kori break; 4577fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_SCTP: 45789ec29343SJun Yang ret = dpaa2_configure_flow_sctp(flow, dev, attr, 45799ec29343SJun Yang &dpaa2_pattern[i], 45809ec29343SJun Yang actions, error, 45815f176728SJun Yang &is_keycfg_configured); 45825f176728SJun Yang if (ret) { 458356c1817dSJun Yang DPAA2_PMD_ERR("SCTP flow config failed!"); 45849ec29343SJun Yang goto end_flow_set; 45855f176728SJun Yang } 4586fe2b986aSSunil Kumar Kori break; 45874cc5cf4aSJun Yang case RTE_FLOW_ITEM_TYPE_ESP: 45884cc5cf4aSJun Yang ret = dpaa2_configure_flow_esp(flow, 45894cc5cf4aSJun Yang dev, attr, &dpaa2_pattern[i], 45904cc5cf4aSJun Yang actions, error, 45914cc5cf4aSJun Yang &is_keycfg_configured); 45924cc5cf4aSJun Yang if (ret) { 45934cc5cf4aSJun Yang DPAA2_PMD_ERR("ESP flow config failed!"); 45944cc5cf4aSJun Yang goto end_flow_set; 45954cc5cf4aSJun Yang } 45964cc5cf4aSJun Yang break; 45974cc5cf4aSJun Yang case RTE_FLOW_ITEM_TYPE_AH: 45984cc5cf4aSJun Yang ret = dpaa2_configure_flow_ah(flow, 45994cc5cf4aSJun Yang dev, attr, &dpaa2_pattern[i], 46004cc5cf4aSJun Yang actions, error, 46014cc5cf4aSJun Yang &is_keycfg_configured); 46024cc5cf4aSJun Yang if (ret) { 46034cc5cf4aSJun Yang DPAA2_PMD_ERR("AH flow config failed!"); 46044cc5cf4aSJun Yang goto end_flow_set; 46054cc5cf4aSJun Yang } 46064cc5cf4aSJun Yang break; 4607fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_GRE: 46089ec29343SJun Yang ret = dpaa2_configure_flow_gre(flow, dev, attr, 46099ec29343SJun Yang &dpaa2_pattern[i], 46109ec29343SJun Yang actions, error, 46115f176728SJun Yang &is_keycfg_configured); 46125f176728SJun Yang if (ret) { 461356c1817dSJun Yang DPAA2_PMD_ERR("GRE flow config failed!"); 46149ec29343SJun Yang goto end_flow_set; 46155f176728SJun Yang } 4616fe2b986aSSunil Kumar Kori break; 461739c8044fSJun Yang case RTE_FLOW_ITEM_TYPE_VXLAN: 46189ec29343SJun Yang ret = dpaa2_configure_flow_vxlan(flow, dev, attr, 46199ec29343SJun Yang &dpaa2_pattern[i], 46209ec29343SJun Yang actions, error, 462139c8044fSJun Yang &is_keycfg_configured); 462239c8044fSJun Yang if (ret) { 462339c8044fSJun Yang DPAA2_PMD_ERR("VXLAN flow config failed!"); 46249ec29343SJun Yang goto end_flow_set; 462539c8044fSJun Yang } 462639c8044fSJun Yang break; 4627a8a6b82eSJun Yang case RTE_FLOW_ITEM_TYPE_ECPRI: 4628a8a6b82eSJun Yang ret = dpaa2_configure_flow_ecpri(flow, 4629a8a6b82eSJun Yang dev, attr, &dpaa2_pattern[i], 4630a8a6b82eSJun Yang actions, error, 4631a8a6b82eSJun Yang &is_keycfg_configured); 4632a8a6b82eSJun Yang if (ret) { 4633a8a6b82eSJun Yang DPAA2_PMD_ERR("ECPRI flow config failed!"); 4634a8a6b82eSJun Yang goto end_flow_set; 4635a8a6b82eSJun Yang } 4636a8a6b82eSJun Yang break; 4637146c745eSJun Yang case RTE_FLOW_ITEM_TYPE_GTP: 4638146c745eSJun Yang ret = dpaa2_configure_flow_gtp(flow, 4639146c745eSJun Yang dev, attr, &dpaa2_pattern[i], 4640146c745eSJun Yang actions, error, 4641146c745eSJun Yang &is_keycfg_configured); 4642146c745eSJun Yang if (ret) { 4643146c745eSJun Yang DPAA2_PMD_ERR("GTP flow config failed!"); 4644146c745eSJun Yang goto end_flow_set; 4645146c745eSJun Yang } 4646146c745eSJun Yang break; 46473f881f8dSNipun Gupta case RTE_FLOW_ITEM_TYPE_RAW: 46489ec29343SJun Yang ret = dpaa2_configure_flow_raw(flow, dev, attr, 46499ec29343SJun Yang &dpaa2_pattern[i], 46503f881f8dSNipun Gupta actions, error, 46513f881f8dSNipun Gupta &is_keycfg_configured); 46523f881f8dSNipun Gupta if (ret) { 465356c1817dSJun Yang DPAA2_PMD_ERR("RAW flow config failed!"); 46549ec29343SJun Yang goto end_flow_set; 46553f881f8dSNipun Gupta } 46563f881f8dSNipun Gupta break; 4657fe2b986aSSunil Kumar Kori case RTE_FLOW_ITEM_TYPE_END: 4658fe2b986aSSunil Kumar Kori end_of_list = 1; 4659fe2b986aSSunil Kumar Kori break; /*End of List*/ 4660fe2b986aSSunil Kumar Kori default: 4661a8a6b82eSJun Yang DPAA2_PMD_ERR("Invalid flow item[%d] type(%d)", 4662a8a6b82eSJun Yang i, pattern[i].type); 4663fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4664fe2b986aSSunil Kumar Kori break; 4665fe2b986aSSunil Kumar Kori } 4666fe2b986aSSunil Kumar Kori i++; 4667fe2b986aSSunil Kumar Kori } 4668fe2b986aSSunil Kumar Kori 466956c1817dSJun Yang qos_key_extract = &priv->extract.qos_key_extract; 467056c1817dSJun Yang key_size = qos_key_extract->key_profile.key_max_size; 467156c1817dSJun Yang flow->qos_rule.key_size = dpaa2_flow_entry_size(key_size); 467256c1817dSJun Yang 467356c1817dSJun Yang tc_key_extract = &priv->extract.tc_key_extract[flow->tc_id]; 467456c1817dSJun Yang key_size = tc_key_extract->key_profile.key_max_size; 467556c1817dSJun Yang flow->fs_rule.key_size = dpaa2_flow_entry_size(key_size); 467656c1817dSJun Yang 4677fe2b986aSSunil Kumar Kori /* Let's parse action on matching traffic */ 4678fe2b986aSSunil Kumar Kori end_of_list = 0; 4679fe2b986aSSunil Kumar Kori while (!end_of_list) { 4680fe2b986aSSunil Kumar Kori switch (actions[j].type) { 4681fe2b986aSSunil Kumar Kori case RTE_FLOW_ACTION_TYPE_QUEUE: 4682b1e15294SIvan Malov case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 4683028d1dfdSJun Yang case RTE_FLOW_ACTION_TYPE_PORT_ID: 468456c1817dSJun Yang ret = dpaa2_configure_flow_fs_action(priv, flow, 4685028d1dfdSJun Yang &actions[j]); 468656c1817dSJun Yang if (ret) 46879ec29343SJun Yang goto end_flow_set; 4688fe2b986aSSunil Kumar Kori 468959303cdfSJun Yang /* Configure FS table first*/ 469056c1817dSJun Yang dist_size = priv->nb_rx_queues / priv->num_rx_tc; 469156c1817dSJun Yang if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) { 469256c1817dSJun Yang ret = dpaa2_configure_fs_rss_table(priv, 469356c1817dSJun Yang flow->tc_id, 469456c1817dSJun Yang dist_size, 469556c1817dSJun Yang false); 469656c1817dSJun Yang if (ret) 46979ec29343SJun Yang goto end_flow_set; 4698fe2b986aSSunil Kumar Kori } 4699fe2b986aSSunil Kumar Kori 470059303cdfSJun Yang /* Configure QoS table then.*/ 470156c1817dSJun Yang if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) { 470256c1817dSJun Yang ret = dpaa2_configure_qos_table(priv, false); 470356c1817dSJun Yang if (ret) 47049ec29343SJun Yang goto end_flow_set; 4705fe2b986aSSunil Kumar Kori } 470656c1817dSJun Yang 470756c1817dSJun Yang if (priv->num_rx_tc > 1) { 470856c1817dSJun Yang ret = dpaa2_flow_add_qos_rule(priv, flow); 470956c1817dSJun Yang if (ret) 47109ec29343SJun Yang goto end_flow_set; 471159303cdfSJun Yang } 4712fe2b986aSSunil Kumar Kori 47134ce58f8aSJun Yang if (flow->tc_index >= priv->fs_entries) { 47145f176728SJun Yang DPAA2_PMD_ERR("FS table with %d entries full", 47154ce58f8aSJun Yang priv->fs_entries); 47165f176728SJun Yang return -1; 47175f176728SJun Yang } 4718d0a77dc3SJun Yang 471956c1817dSJun Yang ret = dpaa2_flow_add_fs_rule(priv, flow); 472056c1817dSJun Yang if (ret) 47219ec29343SJun Yang goto end_flow_set; 472256c1817dSJun Yang 4723fe2b986aSSunil Kumar Kori break; 4724fe2b986aSSunil Kumar Kori case RTE_FLOW_ACTION_TYPE_RSS: 472556c1817dSJun Yang rss_conf = actions[j].conf; 472656c1817dSJun Yang flow->action_type = RTE_FLOW_ACTION_TYPE_RSS; 4727fe2b986aSSunil Kumar Kori 4728fe2b986aSSunil Kumar Kori ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types, 472956c1817dSJun Yang &tc_key_extract->dpkg); 4730fe2b986aSSunil Kumar Kori if (ret < 0) { 473156c1817dSJun Yang DPAA2_PMD_ERR("TC[%d] distset RSS failed", 473256c1817dSJun Yang flow->tc_id); 47339ec29343SJun Yang goto end_flow_set; 4734fe2b986aSSunil Kumar Kori } 4735fe2b986aSSunil Kumar Kori 473656c1817dSJun Yang dist_size = rss_conf->queue_num; 473756c1817dSJun Yang if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) { 473856c1817dSJun Yang ret = dpaa2_configure_fs_rss_table(priv, 473956c1817dSJun Yang flow->tc_id, 474056c1817dSJun Yang dist_size, 474156c1817dSJun Yang true); 474256c1817dSJun Yang if (ret) 47439ec29343SJun Yang goto end_flow_set; 4744fe2b986aSSunil Kumar Kori } 474556c1817dSJun Yang 474656c1817dSJun Yang if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) { 474756c1817dSJun Yang ret = dpaa2_configure_qos_table(priv, true); 474856c1817dSJun Yang if (ret) 47499ec29343SJun Yang goto end_flow_set; 475056c1817dSJun Yang } 475156c1817dSJun Yang 475256c1817dSJun Yang ret = dpaa2_flow_add_qos_rule(priv, flow); 475356c1817dSJun Yang if (ret) 47549ec29343SJun Yang goto end_flow_set; 475556c1817dSJun Yang 475656c1817dSJun Yang ret = dpaa2_flow_add_fs_rule(priv, flow); 475756c1817dSJun Yang if (ret) 47589ec29343SJun Yang goto end_flow_set; 475956c1817dSJun Yang 4760fe2b986aSSunil Kumar Kori break; 476139c8044fSJun Yang case RTE_FLOW_ACTION_TYPE_PF: 476239c8044fSJun Yang /* Skip this action, have to add for vxlan */ 476339c8044fSJun Yang break; 4764fe2b986aSSunil Kumar Kori case RTE_FLOW_ACTION_TYPE_END: 4765fe2b986aSSunil Kumar Kori end_of_list = 1; 4766fe2b986aSSunil Kumar Kori break; 4767fe2b986aSSunil Kumar Kori default: 4768fe2b986aSSunil Kumar Kori DPAA2_PMD_ERR("Invalid action type"); 4769fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4770fe2b986aSSunil Kumar Kori break; 4771fe2b986aSSunil Kumar Kori } 4772fe2b986aSSunil Kumar Kori j++; 4773fe2b986aSSunil Kumar Kori } 4774fe2b986aSSunil Kumar Kori 47759ec29343SJun Yang end_flow_set: 47766a556bd6SHemant Agrawal if (!ret) { 47776a556bd6SHemant Agrawal /* New rules are inserted. */ 47786a556bd6SHemant Agrawal if (!curr) { 47796a556bd6SHemant Agrawal LIST_INSERT_HEAD(&priv->flows, flow, next); 47806a556bd6SHemant Agrawal } else { 47816a556bd6SHemant Agrawal while (LIST_NEXT(curr, next)) 47826a556bd6SHemant Agrawal curr = LIST_NEXT(curr, next); 47836a556bd6SHemant Agrawal LIST_INSERT_AFTER(curr, flow, next); 47846a556bd6SHemant Agrawal } 47856a556bd6SHemant Agrawal } 47869ec29343SJun Yang 47879ec29343SJun Yang rte_free(dpaa2_pattern); 47889ec29343SJun Yang 4789fe2b986aSSunil Kumar Kori return ret; 4790fe2b986aSSunil Kumar Kori } 4791fe2b986aSSunil Kumar Kori 4792fe2b986aSSunil Kumar Kori static inline int 4793fe2b986aSSunil Kumar Kori dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr, 4794fe2b986aSSunil Kumar Kori const struct rte_flow_attr *attr) 4795fe2b986aSSunil Kumar Kori { 4796fe2b986aSSunil Kumar Kori int ret = 0; 4797fe2b986aSSunil Kumar Kori 4798fe2b986aSSunil Kumar Kori if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) { 47991cf6d181SJun Yang DPAA2_PMD_ERR("Group/TC(%d) is out of range(%d)", 48001cf6d181SJun Yang attr->group, dpni_attr->num_rx_tcs); 4801fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4802fe2b986aSSunil Kumar Kori } 4803fe2b986aSSunil Kumar Kori if (unlikely(attr->priority >= dpni_attr->fs_entries)) { 48041cf6d181SJun Yang DPAA2_PMD_ERR("Priority(%d) within group is out of range(%d)", 48051cf6d181SJun Yang attr->priority, dpni_attr->fs_entries); 4806fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4807fe2b986aSSunil Kumar Kori } 4808fe2b986aSSunil Kumar Kori if (unlikely(attr->egress)) { 48091cf6d181SJun Yang DPAA2_PMD_ERR("Egress flow configuration is not supported"); 4810fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4811fe2b986aSSunil Kumar Kori } 4812fe2b986aSSunil Kumar Kori if (unlikely(!attr->ingress)) { 4813f665790aSDavid Marchand DPAA2_PMD_ERR("Ingress flag must be configured"); 4814fe2b986aSSunil Kumar Kori ret = -EINVAL; 4815fe2b986aSSunil Kumar Kori } 4816fe2b986aSSunil Kumar Kori return ret; 4817fe2b986aSSunil Kumar Kori } 4818fe2b986aSSunil Kumar Kori 4819fe2b986aSSunil Kumar Kori static inline int 48205f176728SJun Yang dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[]) 4821fe2b986aSSunil Kumar Kori { 48225f176728SJun Yang unsigned int i, j, is_found = 0; 4823fe2b986aSSunil Kumar Kori int ret = 0; 48241cf6d181SJun Yang const enum rte_flow_item_type *hp_supported; 48251cf6d181SJun Yang const enum rte_flow_item_type *sp_supported; 48261cf6d181SJun Yang uint64_t hp_supported_num, sp_supported_num; 48271cf6d181SJun Yang 48281cf6d181SJun Yang hp_supported = dpaa2_hp_supported_pattern_type; 48291cf6d181SJun Yang hp_supported_num = RTE_DIM(dpaa2_hp_supported_pattern_type); 48301cf6d181SJun Yang 48311cf6d181SJun Yang sp_supported = dpaa2_sp_supported_pattern_type; 48321cf6d181SJun Yang sp_supported_num = RTE_DIM(dpaa2_sp_supported_pattern_type); 4833fe2b986aSSunil Kumar Kori 4834fe2b986aSSunil Kumar Kori for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) { 48351cf6d181SJun Yang is_found = 0; 48361cf6d181SJun Yang for (i = 0; i < hp_supported_num; i++) { 48371cf6d181SJun Yang if (hp_supported[i] == pattern[j].type) { 4838fe2b986aSSunil Kumar Kori is_found = 1; 4839fe2b986aSSunil Kumar Kori break; 4840fe2b986aSSunil Kumar Kori } 4841fe2b986aSSunil Kumar Kori } 48421cf6d181SJun Yang if (is_found) 48431cf6d181SJun Yang continue; 48441cf6d181SJun Yang if (dpaa2_sp_loaded > 0) { 48451cf6d181SJun Yang for (i = 0; i < sp_supported_num; i++) { 48461cf6d181SJun Yang if (sp_supported[i] == pattern[j].type) { 48471cf6d181SJun Yang is_found = 1; 4848fe2b986aSSunil Kumar Kori break; 4849fe2b986aSSunil Kumar Kori } 4850fe2b986aSSunil Kumar Kori } 48511cf6d181SJun Yang } 48521cf6d181SJun Yang if (!is_found) { 48531cf6d181SJun Yang DPAA2_PMD_WARN("Flow type(%d) not supported", 48541cf6d181SJun Yang pattern[j].type); 48551cf6d181SJun Yang ret = -ENOTSUP; 4856fe2b986aSSunil Kumar Kori break; 4857fe2b986aSSunil Kumar Kori } 4858fe2b986aSSunil Kumar Kori } 4859fe2b986aSSunil Kumar Kori 4860fe2b986aSSunil Kumar Kori return ret; 4861fe2b986aSSunil Kumar Kori } 4862fe2b986aSSunil Kumar Kori 4863fe2b986aSSunil Kumar Kori static inline int 4864fe2b986aSSunil Kumar Kori dpaa2_dev_verify_actions(const struct rte_flow_action actions[]) 4865fe2b986aSSunil Kumar Kori { 4866fe2b986aSSunil Kumar Kori unsigned int i, j, is_found = 0; 4867fe2b986aSSunil Kumar Kori int ret = 0; 4868fe2b986aSSunil Kumar Kori 4869fe2b986aSSunil Kumar Kori for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { 4870fe2b986aSSunil Kumar Kori for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) { 4871fe2b986aSSunil Kumar Kori if (dpaa2_supported_action_type[i] == actions[j].type) { 4872fe2b986aSSunil Kumar Kori is_found = 1; 4873fe2b986aSSunil Kumar Kori break; 4874fe2b986aSSunil Kumar Kori } 4875fe2b986aSSunil Kumar Kori } 4876fe2b986aSSunil Kumar Kori if (!is_found) { 4877fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 4878fe2b986aSSunil Kumar Kori break; 4879fe2b986aSSunil Kumar Kori } 4880fe2b986aSSunil Kumar Kori } 4881fe2b986aSSunil Kumar Kori for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { 48825f176728SJun Yang if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP && 48835f176728SJun Yang !actions[j].conf) 4884fe2b986aSSunil Kumar Kori ret = -EINVAL; 4885fe2b986aSSunil Kumar Kori } 4886fe2b986aSSunil Kumar Kori return ret; 4887fe2b986aSSunil Kumar Kori } 4888fe2b986aSSunil Kumar Kori 488956c1817dSJun Yang static int 489056c1817dSJun Yang dpaa2_flow_validate(struct rte_eth_dev *dev, 4891fe2b986aSSunil Kumar Kori const struct rte_flow_attr *flow_attr, 4892fe2b986aSSunil Kumar Kori const struct rte_flow_item pattern[], 4893fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[], 48946a556bd6SHemant Agrawal struct rte_flow_error *error) 4895fe2b986aSSunil Kumar Kori { 4896fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 4897fe2b986aSSunil Kumar Kori struct dpni_attr dpni_attr; 4898fe2b986aSSunil Kumar Kori struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 4899fe2b986aSSunil Kumar Kori uint16_t token = priv->token; 4900fe2b986aSSunil Kumar Kori int ret = 0; 4901fe2b986aSSunil Kumar Kori 4902fe2b986aSSunil Kumar Kori memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 4903fe2b986aSSunil Kumar Kori ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr); 4904fe2b986aSSunil Kumar Kori if (ret < 0) { 49051cf6d181SJun Yang DPAA2_PMD_ERR("Get dpni@%d attribute failed(%d)", 49061cf6d181SJun Yang priv->hw_id, ret); 49076a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 49086a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_ATTR, 49096a556bd6SHemant Agrawal flow_attr, "invalid"); 4910fe2b986aSSunil Kumar Kori return ret; 4911fe2b986aSSunil Kumar Kori } 4912fe2b986aSSunil Kumar Kori 4913fe2b986aSSunil Kumar Kori /* Verify input attributes */ 4914fe2b986aSSunil Kumar Kori ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr); 4915fe2b986aSSunil Kumar Kori if (ret < 0) { 49161cf6d181SJun Yang DPAA2_PMD_ERR("Invalid attributes are given"); 49176a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 49186a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_ATTR, 49196a556bd6SHemant Agrawal flow_attr, "invalid"); 4920fe2b986aSSunil Kumar Kori goto not_valid_params; 4921fe2b986aSSunil Kumar Kori } 4922fe2b986aSSunil Kumar Kori /* Verify input pattern list */ 49235f176728SJun Yang ret = dpaa2_dev_verify_patterns(pattern); 4924fe2b986aSSunil Kumar Kori if (ret < 0) { 49251cf6d181SJun Yang DPAA2_PMD_ERR("Invalid pattern list is given"); 49266a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 49276a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_ITEM, 49286a556bd6SHemant Agrawal pattern, "invalid"); 4929fe2b986aSSunil Kumar Kori goto not_valid_params; 4930fe2b986aSSunil Kumar Kori } 4931fe2b986aSSunil Kumar Kori /* Verify input action list */ 4932fe2b986aSSunil Kumar Kori ret = dpaa2_dev_verify_actions(actions); 4933fe2b986aSSunil Kumar Kori if (ret < 0) { 49341cf6d181SJun Yang DPAA2_PMD_ERR("Invalid action list is given"); 49356a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 49366a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_ACTION, 49376a556bd6SHemant Agrawal actions, "invalid"); 4938fe2b986aSSunil Kumar Kori goto not_valid_params; 4939fe2b986aSSunil Kumar Kori } 4940fe2b986aSSunil Kumar Kori not_valid_params: 4941fe2b986aSSunil Kumar Kori return ret; 4942fe2b986aSSunil Kumar Kori } 4943fe2b986aSSunil Kumar Kori 494456c1817dSJun Yang static struct rte_flow * 494556c1817dSJun Yang dpaa2_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, 4946fe2b986aSSunil Kumar Kori const struct rte_flow_item pattern[], 4947fe2b986aSSunil Kumar Kori const struct rte_flow_action actions[], 4948fe2b986aSSunil Kumar Kori struct rte_flow_error *error) 4949fe2b986aSSunil Kumar Kori { 495056c1817dSJun Yang struct dpaa2_dev_flow *flow = NULL; 495156c1817dSJun Yang struct dpaa2_dev_priv *priv = dev->data->dev_private; 4952fe2b986aSSunil Kumar Kori int ret; 495325d0ae62SJun Yang uint64_t iova; 4954fe2b986aSSunil Kumar Kori 4955f5ed2ea0SJun Yang dpaa2_flow_control_log = 4956f5ed2ea0SJun Yang getenv("DPAA2_FLOW_CONTROL_LOG"); 4957f5ed2ea0SJun Yang 495840f84025SJun Yang if (getenv("DPAA2_FLOW_CONTROL_MISS_FLOW")) { 495940f84025SJun Yang dpaa2_flow_miss_flow_id = 4960068be45fSRohit Raj (uint16_t)atoi(getenv("DPAA2_FLOW_CONTROL_MISS_FLOW")); 496140f84025SJun Yang if (dpaa2_flow_miss_flow_id >= priv->dist_queues) { 496256c1817dSJun Yang DPAA2_PMD_ERR("Missed flow ID %d >= dist size(%d)", 496340f84025SJun Yang dpaa2_flow_miss_flow_id, 496456c1817dSJun Yang priv->dist_queues); 496540f84025SJun Yang return NULL; 496640f84025SJun Yang } 496740f84025SJun Yang } 496840f84025SJun Yang 496956c1817dSJun Yang flow = rte_zmalloc(NULL, sizeof(struct dpaa2_dev_flow), 497056c1817dSJun Yang RTE_CACHE_LINE_SIZE); 4971fe2b986aSSunil Kumar Kori if (!flow) { 4972fe2b986aSSunil Kumar Kori DPAA2_PMD_ERR("Failure to allocate memory for flow"); 49736a556bd6SHemant Agrawal goto mem_failure; 4974fe2b986aSSunil Kumar Kori } 497556c1817dSJun Yang 497656c1817dSJun Yang /* Allocate DMA'ble memory to write the qos rules */ 497725d0ae62SJun Yang flow->qos_key_addr = rte_zmalloc(NULL, 497825d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE); 497956c1817dSJun Yang if (!flow->qos_key_addr) { 498056c1817dSJun Yang DPAA2_PMD_ERR("Memory allocation failed"); 49816a556bd6SHemant Agrawal goto mem_failure; 4982fe2b986aSSunil Kumar Kori } 498325d0ae62SJun Yang iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_key_addr, 498425d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE); 498525d0ae62SJun Yang if (iova == RTE_BAD_IOVA) { 498625d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for qos key(%p)", 498725d0ae62SJun Yang __func__, flow->qos_key_addr); 498825d0ae62SJun Yang goto mem_failure; 498925d0ae62SJun Yang } 499025d0ae62SJun Yang flow->qos_rule.key_iova = iova; 499156c1817dSJun Yang 499225d0ae62SJun Yang flow->qos_mask_addr = rte_zmalloc(NULL, 499325d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE); 499456c1817dSJun Yang if (!flow->qos_mask_addr) { 499556c1817dSJun Yang DPAA2_PMD_ERR("Memory allocation failed"); 49966a556bd6SHemant Agrawal goto mem_failure; 4997fe2b986aSSunil Kumar Kori } 499825d0ae62SJun Yang iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_mask_addr, 499925d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE); 500025d0ae62SJun Yang if (iova == RTE_BAD_IOVA) { 500125d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for qos mask(%p)", 500225d0ae62SJun Yang __func__, flow->qos_mask_addr); 500325d0ae62SJun Yang goto mem_failure; 500425d0ae62SJun Yang } 500525d0ae62SJun Yang flow->qos_rule.mask_iova = iova; 5006fe2b986aSSunil Kumar Kori 500756c1817dSJun Yang /* Allocate DMA'ble memory to write the FS rules */ 500825d0ae62SJun Yang flow->fs_key_addr = rte_zmalloc(NULL, 500925d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE); 501056c1817dSJun Yang if (!flow->fs_key_addr) { 501156c1817dSJun Yang DPAA2_PMD_ERR("Memory allocation failed"); 50125f176728SJun Yang goto mem_failure; 50135f176728SJun Yang } 501425d0ae62SJun Yang iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_key_addr, 501525d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE); 501625d0ae62SJun Yang if (iova == RTE_BAD_IOVA) { 501725d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for fs key(%p)", 501825d0ae62SJun Yang __func__, flow->fs_key_addr); 501925d0ae62SJun Yang goto mem_failure; 502025d0ae62SJun Yang } 502125d0ae62SJun Yang flow->fs_rule.key_iova = iova; 502256c1817dSJun Yang 502325d0ae62SJun Yang flow->fs_mask_addr = rte_zmalloc(NULL, 502425d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE); 502556c1817dSJun Yang if (!flow->fs_mask_addr) { 502656c1817dSJun Yang DPAA2_PMD_ERR("Memory allocation failed"); 50275f176728SJun Yang goto mem_failure; 50285f176728SJun Yang } 502925d0ae62SJun Yang iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_mask_addr, 503025d0ae62SJun Yang DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE); 503125d0ae62SJun Yang if (iova == RTE_BAD_IOVA) { 503225d0ae62SJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for fs mask(%p)", 503325d0ae62SJun Yang __func__, flow->fs_mask_addr); 503425d0ae62SJun Yang goto mem_failure; 503525d0ae62SJun Yang } 503625d0ae62SJun Yang flow->fs_rule.mask_iova = iova; 50375f176728SJun Yang 503856c1817dSJun Yang priv->curr = flow; 50395f176728SJun Yang 504056c1817dSJun Yang ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, actions, error); 5041fe2b986aSSunil Kumar Kori if (ret < 0) { 5042028d1dfdSJun Yang if (error && error->type > RTE_FLOW_ERROR_TYPE_ACTION) 50436a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 50446a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 50456a556bd6SHemant Agrawal attr, "unknown"); 504656c1817dSJun Yang DPAA2_PMD_ERR("Create flow failed (%d)", ret); 5047fe2b986aSSunil Kumar Kori goto creation_error; 5048fe2b986aSSunil Kumar Kori } 5049fe2b986aSSunil Kumar Kori 505056c1817dSJun Yang priv->curr = NULL; 505156c1817dSJun Yang return (struct rte_flow *)flow; 505256c1817dSJun Yang 50536a556bd6SHemant Agrawal mem_failure: 505456c1817dSJun Yang rte_flow_error_set(error, EPERM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 505556c1817dSJun Yang "memory alloc"); 505656c1817dSJun Yang 5057fe2b986aSSunil Kumar Kori creation_error: 505856c1817dSJun Yang if (flow) { 505956c1817dSJun Yang rte_free(flow->qos_key_addr); 506056c1817dSJun Yang rte_free(flow->qos_mask_addr); 506156c1817dSJun Yang rte_free(flow->fs_key_addr); 506256c1817dSJun Yang rte_free(flow->fs_mask_addr); 506356c1817dSJun Yang rte_free(flow); 506456c1817dSJun Yang } 506556c1817dSJun Yang priv->curr = NULL; 50666a556bd6SHemant Agrawal 5067fe2b986aSSunil Kumar Kori return NULL; 5068fe2b986aSSunil Kumar Kori } 5069fe2b986aSSunil Kumar Kori 507056c1817dSJun Yang static int 507156c1817dSJun Yang dpaa2_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *_flow, 50726a556bd6SHemant Agrawal struct rte_flow_error *error) 5073fe2b986aSSunil Kumar Kori { 5074fe2b986aSSunil Kumar Kori int ret = 0; 507556c1817dSJun Yang struct dpaa2_dev_flow *flow; 5076fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 507756c1817dSJun Yang struct fsl_mc_io *dpni = priv->hw; 5078fe2b986aSSunil Kumar Kori 507956c1817dSJun Yang flow = (struct dpaa2_dev_flow *)_flow; 508056c1817dSJun Yang 508156c1817dSJun Yang switch (flow->action_type) { 5082fe2b986aSSunil Kumar Kori case RTE_FLOW_ACTION_TYPE_QUEUE: 5083b1e15294SIvan Malov case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 5084028d1dfdSJun Yang case RTE_FLOW_ACTION_TYPE_PORT_ID: 508559303cdfSJun Yang if (priv->num_rx_tc > 1) { 5086fe2b986aSSunil Kumar Kori /* Remove entry from QoS table first */ 508756c1817dSJun Yang ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, 508856c1817dSJun Yang priv->token, 50895f176728SJun Yang &flow->qos_rule); 5090fe2b986aSSunil Kumar Kori if (ret < 0) { 509156c1817dSJun Yang DPAA2_PMD_ERR("Remove FS QoS entry failed"); 509256c1817dSJun Yang dpaa2_flow_qos_entry_log("Delete failed", flow, 509356c1817dSJun Yang -1); 509456c1817dSJun Yang abort(); 5095fe2b986aSSunil Kumar Kori goto error; 5096fe2b986aSSunil Kumar Kori } 509759303cdfSJun Yang } 5098fe2b986aSSunil Kumar Kori 5099fe2b986aSSunil Kumar Kori /* Then remove entry from FS table */ 5100fe2b986aSSunil Kumar Kori ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token, 51015f176728SJun Yang flow->tc_id, &flow->fs_rule); 5102fe2b986aSSunil Kumar Kori if (ret < 0) { 510356c1817dSJun Yang DPAA2_PMD_ERR("Remove entry from FS[%d] failed", 510456c1817dSJun Yang flow->tc_id); 5105fe2b986aSSunil Kumar Kori goto error; 5106fe2b986aSSunil Kumar Kori } 5107fe2b986aSSunil Kumar Kori break; 5108fe2b986aSSunil Kumar Kori case RTE_FLOW_ACTION_TYPE_RSS: 510959303cdfSJun Yang if (priv->num_rx_tc > 1) { 511056c1817dSJun Yang ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, 511156c1817dSJun Yang priv->token, 51125f176728SJun Yang &flow->qos_rule); 5113fe2b986aSSunil Kumar Kori if (ret < 0) { 511456c1817dSJun Yang DPAA2_PMD_ERR("Remove RSS QoS entry failed"); 5115fe2b986aSSunil Kumar Kori goto error; 5116fe2b986aSSunil Kumar Kori } 511759303cdfSJun Yang } 5118fe2b986aSSunil Kumar Kori break; 5119fe2b986aSSunil Kumar Kori default: 512056c1817dSJun Yang DPAA2_PMD_ERR("Action(%d) not supported", flow->action_type); 5121fe2b986aSSunil Kumar Kori ret = -ENOTSUP; 5122fe2b986aSSunil Kumar Kori break; 5123fe2b986aSSunil Kumar Kori } 5124fe2b986aSSunil Kumar Kori 51256a556bd6SHemant Agrawal LIST_REMOVE(flow, next); 512656c1817dSJun Yang rte_free(flow->qos_key_addr); 512756c1817dSJun Yang rte_free(flow->qos_mask_addr); 512856c1817dSJun Yang rte_free(flow->fs_key_addr); 512956c1817dSJun Yang rte_free(flow->fs_mask_addr); 5130fe2b986aSSunil Kumar Kori /* Now free the flow */ 5131fe2b986aSSunil Kumar Kori rte_free(flow); 5132fe2b986aSSunil Kumar Kori 5133fe2b986aSSunil Kumar Kori error: 51346a556bd6SHemant Agrawal if (ret) 51356a556bd6SHemant Agrawal rte_flow_error_set(error, EPERM, 51366a556bd6SHemant Agrawal RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 51376a556bd6SHemant Agrawal NULL, "unknown"); 5138fe2b986aSSunil Kumar Kori return ret; 5139fe2b986aSSunil Kumar Kori } 5140fe2b986aSSunil Kumar Kori 51416a556bd6SHemant Agrawal /** 51426a556bd6SHemant Agrawal * Destroy user-configured flow rules. 51436a556bd6SHemant Agrawal * 51446a556bd6SHemant Agrawal * This function skips internal flows rules. 51456a556bd6SHemant Agrawal * 51466a556bd6SHemant Agrawal * @see rte_flow_flush() 51476a556bd6SHemant Agrawal * @see rte_flow_ops 51486a556bd6SHemant Agrawal */ 5149fe2b986aSSunil Kumar Kori static int 5150fe2b986aSSunil Kumar Kori dpaa2_flow_flush(struct rte_eth_dev *dev, 51516a556bd6SHemant Agrawal struct rte_flow_error *error) 5152fe2b986aSSunil Kumar Kori { 5153fe2b986aSSunil Kumar Kori struct dpaa2_dev_priv *priv = dev->data->dev_private; 515456c1817dSJun Yang struct dpaa2_dev_flow *flow = LIST_FIRST(&priv->flows); 5155fe2b986aSSunil Kumar Kori 51566a556bd6SHemant Agrawal while (flow) { 515756c1817dSJun Yang struct dpaa2_dev_flow *next = LIST_NEXT(flow, next); 5158fe2b986aSSunil Kumar Kori 515956c1817dSJun Yang dpaa2_flow_destroy(dev, (struct rte_flow *)flow, error); 51606a556bd6SHemant Agrawal flow = next; 5161fe2b986aSSunil Kumar Kori } 51626a556bd6SHemant Agrawal return 0; 5163fe2b986aSSunil Kumar Kori } 5164fe2b986aSSunil Kumar Kori 5165fe2b986aSSunil Kumar Kori static int 5166fe2b986aSSunil Kumar Kori dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused, 516756c1817dSJun Yang struct rte_flow *_flow __rte_unused, 5168fe2b986aSSunil Kumar Kori const struct rte_flow_action *actions __rte_unused, 5169fe2b986aSSunil Kumar Kori void *data __rte_unused, 5170fe2b986aSSunil Kumar Kori struct rte_flow_error *error __rte_unused) 5171fe2b986aSSunil Kumar Kori { 5172fe2b986aSSunil Kumar Kori return 0; 5173fe2b986aSSunil Kumar Kori } 5174fe2b986aSSunil Kumar Kori 51756a556bd6SHemant Agrawal /** 51766a556bd6SHemant Agrawal * Clean up all flow rules. 51776a556bd6SHemant Agrawal * 51786a556bd6SHemant Agrawal * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow 51796a556bd6SHemant Agrawal * rules regardless of whether they are internal or user-configured. 51806a556bd6SHemant Agrawal * 51816a556bd6SHemant Agrawal * @param priv 51826a556bd6SHemant Agrawal * Pointer to private structure. 51836a556bd6SHemant Agrawal */ 51846a556bd6SHemant Agrawal void 51856a556bd6SHemant Agrawal dpaa2_flow_clean(struct rte_eth_dev *dev) 51866a556bd6SHemant Agrawal { 518756c1817dSJun Yang struct dpaa2_dev_flow *flow; 51886a556bd6SHemant Agrawal struct dpaa2_dev_priv *priv = dev->data->dev_private; 51896a556bd6SHemant Agrawal 51906a556bd6SHemant Agrawal while ((flow = LIST_FIRST(&priv->flows))) 519156c1817dSJun Yang dpaa2_flow_destroy(dev, (struct rte_flow *)flow, NULL); 51926a556bd6SHemant Agrawal } 51936a556bd6SHemant Agrawal 5194fe2b986aSSunil Kumar Kori const struct rte_flow_ops dpaa2_flow_ops = { 5195fe2b986aSSunil Kumar Kori .create = dpaa2_flow_create, 5196fe2b986aSSunil Kumar Kori .validate = dpaa2_flow_validate, 5197fe2b986aSSunil Kumar Kori .destroy = dpaa2_flow_destroy, 5198fe2b986aSSunil Kumar Kori .flush = dpaa2_flow_flush, 5199fe2b986aSSunil Kumar Kori .query = dpaa2_flow_query, 5200fe2b986aSSunil Kumar Kori }; 5201