1795ac238SJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause 2795ac238SJerin Jacob * Copyright(C) 2021 Marvell. 3795ac238SJerin Jacob */ 4795ac238SJerin Jacob #include <cnxk_flow.h> 5c1ae225eSHarman Kalra #include <cnxk_rep.h> 6795ac238SJerin Jacob 7d11278e3SHarman Kalra #define IS_REP_BIT 7 8c2f3e9e7SHarman Kalra 9c2f3e9e7SHarman Kalra #define TNL_DCP_MATCH_ID 5 10c2f3e9e7SHarman Kalra #define NRML_MATCH_ID 1 11795ac238SJerin Jacob const struct cnxk_rte_flow_term_info term[] = { 1200701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH, sizeof(struct rte_flow_item_eth)}, 1300701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN, sizeof(struct rte_flow_item_vlan)}, 1400701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG, sizeof(struct rte_flow_item_e_tag)}, 1500701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4, sizeof(struct rte_flow_item_ipv4)}, 1600701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6, sizeof(struct rte_flow_item_ipv6)}, 1700701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT, 18a800675bSSatheesh Paul sizeof(struct rte_flow_item_ipv6_frag_ext)}, 1900701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4, 20795ac238SJerin Jacob sizeof(struct rte_flow_item_arp_eth_ipv4)}, 2100701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS, sizeof(struct rte_flow_item_mpls)}, 2200701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP, sizeof(struct rte_flow_item_icmp)}, 2300701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP, sizeof(struct rte_flow_item_udp)}, 2400701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP, sizeof(struct rte_flow_item_tcp)}, 2500701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP, sizeof(struct rte_flow_item_sctp)}, 2600701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP, sizeof(struct rte_flow_item_esp)}, 2700701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE, sizeof(struct rte_flow_item_gre)}, 2800701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE, sizeof(struct rte_flow_item_nvgre)}, 2900701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN, sizeof(struct rte_flow_item_vxlan)}, 3000701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC, sizeof(struct rte_flow_item_gtp)}, 3100701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU, sizeof(struct rte_flow_item_gtp)}, 32795ac238SJerin Jacob [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE, 33795ac238SJerin Jacob sizeof(struct rte_flow_item_geneve)}, 3400701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {ROC_NPC_ITEM_TYPE_VXLAN_GPE, 35795ac238SJerin Jacob sizeof(struct rte_flow_item_vxlan_gpe)}, 36795ac238SJerin Jacob [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT, 37795ac238SJerin Jacob sizeof(struct rte_flow_item_ipv6_ext)}, 38795ac238SJerin Jacob [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0}, 39795ac238SJerin Jacob [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0}, 4000701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY, sizeof(uint32_t)}, 41795ac238SJerin Jacob [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2, 42795ac238SJerin Jacob sizeof(struct rte_flow_item_higig2_hdr)}, 4300701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW, sizeof(struct rte_flow_item_raw)}, 4400701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_MARK] = {ROC_NPC_ITEM_TYPE_MARK, sizeof(struct rte_flow_item_mark)}, 45986739d9SSatheesh Paul [RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_ROUTING_EXT, 46986739d9SSatheesh Paul sizeof(struct rte_flow_item_ipv6_routing_ext)}, 4728896009SSatheesh Paul [RTE_FLOW_ITEM_TYPE_TX_QUEUE] = {ROC_NPC_ITEM_TYPE_TX_QUEUE, 48db715b94SSatheesh Paul sizeof(struct rte_flow_item_tx_queue)}, 4900701e71SKiran Kumar K [RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT] = {ROC_NPC_ITEM_TYPE_REPRESENTED_PORT, 5000701e71SKiran Kumar K sizeof(struct rte_flow_item_ethdev)}, 51db715b94SSatheesh Paul [RTE_FLOW_ITEM_TYPE_PPPOES] = {ROC_NPC_ITEM_TYPE_PPPOES, 5200701e71SKiran Kumar K sizeof(struct rte_flow_item_pppoe)} 5300701e71SKiran Kumar K }; 54795ac238SJerin Jacob 55795ac238SJerin Jacob static int 56db715b94SSatheesh Paul npc_rss_action_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 57795ac238SJerin Jacob const struct rte_flow_action *act) 58795ac238SJerin Jacob { 59795ac238SJerin Jacob const struct rte_flow_action_rss *rss; 60795ac238SJerin Jacob 61795ac238SJerin Jacob rss = (const struct rte_flow_action_rss *)act->conf; 62795ac238SJerin Jacob 63795ac238SJerin Jacob if (attr->egress) { 64795ac238SJerin Jacob plt_err("No support of RSS in egress"); 65795ac238SJerin Jacob return -EINVAL; 66795ac238SJerin Jacob } 67795ac238SJerin Jacob 68795ac238SJerin Jacob if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) { 69795ac238SJerin Jacob plt_err("multi-queue mode is disabled"); 70795ac238SJerin Jacob return -ENOTSUP; 71795ac238SJerin Jacob } 72795ac238SJerin Jacob 73795ac238SJerin Jacob if (!rss || !rss->queue_num) { 74795ac238SJerin Jacob plt_err("no valid queues"); 75795ac238SJerin Jacob return -EINVAL; 76795ac238SJerin Jacob } 77795ac238SJerin Jacob 78795ac238SJerin Jacob if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) { 79795ac238SJerin Jacob plt_err("non-default RSS hash functions are not supported"); 80795ac238SJerin Jacob return -ENOTSUP; 81795ac238SJerin Jacob } 82795ac238SJerin Jacob 83795ac238SJerin Jacob if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) { 84795ac238SJerin Jacob plt_err("RSS hash key too large"); 85795ac238SJerin Jacob return -ENOTSUP; 86795ac238SJerin Jacob } 87795ac238SJerin Jacob 88795ac238SJerin Jacob return 0; 89795ac238SJerin Jacob } 90795ac238SJerin Jacob 91795ac238SJerin Jacob static void 92752ce2f3SKiran Kumar K npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev, const struct roc_npc_action *rss_action, 93752ce2f3SKiran Kumar K uint32_t *flowkey_cfg, uint64_t default_rss_types) 94795ac238SJerin Jacob { 95795ac238SJerin Jacob const struct roc_npc_action_rss *rss; 96752ce2f3SKiran Kumar K uint64_t rss_types; 97795ac238SJerin Jacob 98795ac238SJerin Jacob rss = (const struct roc_npc_action_rss *)rss_action->conf; 99752ce2f3SKiran Kumar K rss_types = rss->types; 100752ce2f3SKiran Kumar K /* If no RSS types are specified, use default one */ 101752ce2f3SKiran Kumar K if (rss_types == 0) 102752ce2f3SKiran Kumar K rss_types = default_rss_types; 103795ac238SJerin Jacob 104752ce2f3SKiran Kumar K *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss_types, rss->level); 105795ac238SJerin Jacob } 106795ac238SJerin Jacob 107795ac238SJerin Jacob static int 108dd23ff70SSatheesh Paul npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct rte_flow_action *action, 109dd23ff70SSatheesh Paul uint16_t *dst_pf_func, uint16_t *dst_channel) 110dd23ff70SSatheesh Paul { 111dd23ff70SSatheesh Paul const struct rte_flow_action_port_id *port_act; 112dd23ff70SSatheesh Paul struct rte_eth_dev *portid_eth_dev; 113dd23ff70SSatheesh Paul char if_name[RTE_ETH_NAME_MAX_LEN]; 114dd23ff70SSatheesh Paul struct cnxk_eth_dev *hw_dst; 115dd23ff70SSatheesh Paul struct roc_npc *roc_npc_dst; 116dd23ff70SSatheesh Paul int rc = 0; 117dd23ff70SSatheesh Paul 118dd23ff70SSatheesh Paul port_act = (const struct rte_flow_action_port_id *)action->conf; 119dd23ff70SSatheesh Paul 120dd23ff70SSatheesh Paul rc = rte_eth_dev_get_name_by_port(port_act->id, if_name); 121dd23ff70SSatheesh Paul if (rc) { 122dd23ff70SSatheesh Paul plt_err("Name not found for output port id"); 123dd23ff70SSatheesh Paul goto err_exit; 124dd23ff70SSatheesh Paul } 125dd23ff70SSatheesh Paul portid_eth_dev = rte_eth_dev_allocated(if_name); 126dd23ff70SSatheesh Paul if (!portid_eth_dev) { 127dd23ff70SSatheesh Paul plt_err("eth_dev not found for output port id"); 128dd23ff70SSatheesh Paul goto err_exit; 129dd23ff70SSatheesh Paul } 130dd23ff70SSatheesh Paul if (strcmp(portid_eth_dev->device->driver->name, eth_dev->device->driver->name) != 0) { 131dd23ff70SSatheesh Paul plt_err("Output port not under same driver"); 132dd23ff70SSatheesh Paul goto err_exit; 133dd23ff70SSatheesh Paul } 134dd23ff70SSatheesh Paul hw_dst = portid_eth_dev->data->dev_private; 135dd23ff70SSatheesh Paul roc_npc_dst = &hw_dst->npc; 136dd23ff70SSatheesh Paul *dst_pf_func = roc_npc_dst->pf_func; 137dd23ff70SSatheesh Paul *dst_channel = hw_dst->npc.channel; 138dd23ff70SSatheesh Paul 139dd23ff70SSatheesh Paul return 0; 140dd23ff70SSatheesh Paul 141dd23ff70SSatheesh Paul err_exit: 142dd23ff70SSatheesh Paul return -EINVAL; 143dd23ff70SSatheesh Paul } 144dd23ff70SSatheesh Paul 145dd23ff70SSatheesh Paul static int 146dd23ff70SSatheesh Paul roc_npc_parse_sample_subaction(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[], 147dd23ff70SSatheesh Paul struct roc_npc_action_sample *sample_action) 148dd23ff70SSatheesh Paul { 149dd23ff70SSatheesh Paul uint16_t dst_pf_func = 0, dst_channel = 0; 150dd23ff70SSatheesh Paul const struct roc_npc_action_vf *vf_act; 151dd23ff70SSatheesh Paul int rc = 0, count = 0; 152dd23ff70SSatheesh Paul bool is_empty = true; 153dd23ff70SSatheesh Paul 154dd23ff70SSatheesh Paul if (sample_action->ratio != 1) { 155dd23ff70SSatheesh Paul plt_err("Sample ratio must be 1"); 156dd23ff70SSatheesh Paul return -EINVAL; 157dd23ff70SSatheesh Paul } 158dd23ff70SSatheesh Paul 159dd23ff70SSatheesh Paul for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { 160dd23ff70SSatheesh Paul is_empty = false; 161dd23ff70SSatheesh Paul switch (actions->type) { 162dd23ff70SSatheesh Paul case RTE_FLOW_ACTION_TYPE_PF: 163dd23ff70SSatheesh Paul count++; 164dd23ff70SSatheesh Paul sample_action->action_type |= ROC_NPC_ACTION_TYPE_PF; 165dd23ff70SSatheesh Paul break; 166dd23ff70SSatheesh Paul case RTE_FLOW_ACTION_TYPE_VF: 167dd23ff70SSatheesh Paul count++; 168dd23ff70SSatheesh Paul vf_act = (const struct roc_npc_action_vf *)actions->conf; 169dd23ff70SSatheesh Paul sample_action->action_type |= ROC_NPC_ACTION_TYPE_VF; 170dd23ff70SSatheesh Paul sample_action->pf_func = vf_act->id & NPC_PFVF_FUNC_MASK; 171dd23ff70SSatheesh Paul break; 172dd23ff70SSatheesh Paul case RTE_FLOW_ACTION_TYPE_PORT_ID: 173dd23ff70SSatheesh Paul rc = npc_parse_port_id_action(eth_dev, actions, &dst_pf_func, &dst_channel); 174dd23ff70SSatheesh Paul if (rc) 175dd23ff70SSatheesh Paul return -EINVAL; 176dd23ff70SSatheesh Paul 177dd23ff70SSatheesh Paul count++; 178dd23ff70SSatheesh Paul sample_action->action_type |= ROC_NPC_ACTION_TYPE_PORT_ID; 179dd23ff70SSatheesh Paul sample_action->pf_func = dst_pf_func; 180dd23ff70SSatheesh Paul sample_action->channel = dst_channel; 181dd23ff70SSatheesh Paul break; 182dd23ff70SSatheesh Paul default: 183dd23ff70SSatheesh Paul continue; 184dd23ff70SSatheesh Paul } 185dd23ff70SSatheesh Paul } 186dd23ff70SSatheesh Paul 187dd23ff70SSatheesh Paul if (count > 1 || is_empty) 188dd23ff70SSatheesh Paul return -EINVAL; 189dd23ff70SSatheesh Paul 190dd23ff70SSatheesh Paul return 0; 191dd23ff70SSatheesh Paul } 192dd23ff70SSatheesh Paul 193dd23ff70SSatheesh Paul static int 194c2f3e9e7SHarman Kalra append_mark_action(struct roc_npc_action *in_actions, uint8_t has_tunnel_pattern, 195c2f3e9e7SHarman Kalra uint64_t *free_allocs, int *act_cnt) 196c2f3e9e7SHarman Kalra { 197c2f3e9e7SHarman Kalra struct rte_flow_action_mark *act_mark; 198c2f3e9e7SHarman Kalra int i = *act_cnt, j = 0; 199c2f3e9e7SHarman Kalra 200c2f3e9e7SHarman Kalra /* Add Mark action */ 201c2f3e9e7SHarman Kalra i++; 202c2f3e9e7SHarman Kalra act_mark = plt_zmalloc(sizeof(struct rte_flow_action_mark), 0); 203c2f3e9e7SHarman Kalra if (!act_mark) { 204c2f3e9e7SHarman Kalra plt_err("Error allocation memory"); 205c2f3e9e7SHarman Kalra return -ENOMEM; 206c2f3e9e7SHarman Kalra } 207c2f3e9e7SHarman Kalra 208c2f3e9e7SHarman Kalra while (free_allocs[j] != 0) 209c2f3e9e7SHarman Kalra j++; 210c2f3e9e7SHarman Kalra free_allocs[j] = (uint64_t)act_mark; 211c2f3e9e7SHarman Kalra /* Mark ID format: (tunnel type - VxLAN, Geneve << 6) | Tunnel decap */ 212c2f3e9e7SHarman Kalra act_mark->id = 213c2f3e9e7SHarman Kalra has_tunnel_pattern ? ((has_tunnel_pattern << 6) | TNL_DCP_MATCH_ID) : NRML_MATCH_ID; 214c2f3e9e7SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK; 215c2f3e9e7SHarman Kalra in_actions[i].conf = (struct rte_flow_action_mark *)act_mark; 216c2f3e9e7SHarman Kalra 217c2f3e9e7SHarman Kalra plt_rep_dbg("Assigned mark ID %x", act_mark->id); 218c2f3e9e7SHarman Kalra 219c2f3e9e7SHarman Kalra *act_cnt = i; 220c2f3e9e7SHarman Kalra 221c2f3e9e7SHarman Kalra return 0; 222c2f3e9e7SHarman Kalra } 223c2f3e9e7SHarman Kalra 224c2f3e9e7SHarman Kalra static int 225*0981a22eSHarman Kalra append_rss_action(struct cnxk_eth_dev *dev, struct roc_npc_action *in_actions, uint16_t nb_rxq, 226*0981a22eSHarman Kalra uint32_t *flowkey_cfg, uint64_t *free_allocs, uint16_t rss_repte_pf_func, 227*0981a22eSHarman Kalra int *act_cnt) 228*0981a22eSHarman Kalra { 229*0981a22eSHarman Kalra struct roc_npc_action_rss *rss_conf; 230*0981a22eSHarman Kalra int i = *act_cnt, j = 0, l, rc = 0; 231*0981a22eSHarman Kalra uint16_t *queue_arr; 232*0981a22eSHarman Kalra 233*0981a22eSHarman Kalra rss_conf = plt_zmalloc(sizeof(struct roc_npc_action_rss), 0); 234*0981a22eSHarman Kalra if (!rss_conf) { 235*0981a22eSHarman Kalra plt_err("Failed to allocate memory for rss conf"); 236*0981a22eSHarman Kalra rc = -ENOMEM; 237*0981a22eSHarman Kalra goto fail; 238*0981a22eSHarman Kalra } 239*0981a22eSHarman Kalra 240*0981a22eSHarman Kalra /* Add RSS action */ 241*0981a22eSHarman Kalra rss_conf->queue_num = nb_rxq; 242*0981a22eSHarman Kalra queue_arr = calloc(1, rss_conf->queue_num * sizeof(uint16_t)); 243*0981a22eSHarman Kalra if (!queue_arr) { 244*0981a22eSHarman Kalra plt_err("Failed to allocate memory for rss queue"); 245*0981a22eSHarman Kalra rc = -ENOMEM; 246*0981a22eSHarman Kalra goto free_rss; 247*0981a22eSHarman Kalra } 248*0981a22eSHarman Kalra 249*0981a22eSHarman Kalra for (l = 0; l < nb_rxq; l++) 250*0981a22eSHarman Kalra queue_arr[l] = l; 251*0981a22eSHarman Kalra rss_conf->queue = queue_arr; 252*0981a22eSHarman Kalra rss_conf->key = NULL; 253*0981a22eSHarman Kalra rss_conf->types = RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP; 254*0981a22eSHarman Kalra 255*0981a22eSHarman Kalra i++; 256*0981a22eSHarman Kalra 257*0981a22eSHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS; 258*0981a22eSHarman Kalra in_actions[i].conf = (struct roc_npc_action_rss *)rss_conf; 259*0981a22eSHarman Kalra in_actions[i].rss_repte_pf_func = rss_repte_pf_func; 260*0981a22eSHarman Kalra 261*0981a22eSHarman Kalra npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg, 262*0981a22eSHarman Kalra RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP); 263*0981a22eSHarman Kalra 264*0981a22eSHarman Kalra *act_cnt = i; 265*0981a22eSHarman Kalra 266*0981a22eSHarman Kalra while (free_allocs[j] != 0) 267*0981a22eSHarman Kalra j++; 268*0981a22eSHarman Kalra free_allocs[j] = (uint64_t)rss_conf; 269*0981a22eSHarman Kalra 270*0981a22eSHarman Kalra return 0; 271*0981a22eSHarman Kalra free_rss: 272*0981a22eSHarman Kalra rte_free(rss_conf); 273*0981a22eSHarman Kalra fail: 274*0981a22eSHarman Kalra return rc; 275*0981a22eSHarman Kalra } 276*0981a22eSHarman Kalra 277*0981a22eSHarman Kalra static int 278d11278e3SHarman Kalra representor_rep_portid_action(struct roc_npc_action *in_actions, struct rte_eth_dev *eth_dev, 279d11278e3SHarman Kalra struct rte_eth_dev *portid_eth_dev, 280d11278e3SHarman Kalra enum rte_flow_action_type act_type, uint8_t rep_pattern, 281c2f3e9e7SHarman Kalra uint16_t *dst_pf_func, bool is_rep, uint8_t has_tunnel_pattern, 282*0981a22eSHarman Kalra uint64_t *free_allocs, int *act_cnt, uint32_t *flowkey_cfg) 283d11278e3SHarman Kalra { 284d11278e3SHarman Kalra struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 285d11278e3SHarman Kalra struct rte_eth_dev *rep_eth_dev = portid_eth_dev; 286d11278e3SHarman Kalra struct rte_flow_action_of_set_vlan_vid *vlan_vid; 287d11278e3SHarman Kalra struct rte_flow_action_of_set_vlan_pcp *vlan_pcp; 288d11278e3SHarman Kalra struct rte_flow_action_of_push_vlan *push_vlan; 289d11278e3SHarman Kalra struct rte_flow_action_queue *act_q = NULL; 290d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 291d11278e3SHarman Kalra struct roc_npc *npc; 292d11278e3SHarman Kalra uint16_t vlan_tci; 293c2f3e9e7SHarman Kalra int j = 0, rc; 294d11278e3SHarman Kalra 295d11278e3SHarman Kalra /* For inserting an action in the list */ 296d11278e3SHarman Kalra int i = *act_cnt; 297d11278e3SHarman Kalra 298d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(rep_eth_dev); 299d11278e3SHarman Kalra if (!is_rep) { 300d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 301d11278e3SHarman Kalra npc = &dev->npc; 302d11278e3SHarman Kalra } else { 303d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 304d11278e3SHarman Kalra } 305d11278e3SHarman Kalra if (rep_pattern >> IS_REP_BIT) { /* Check for normal/representor port as action */ 306d11278e3SHarman Kalra if ((rep_pattern & 0x7f) == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) { 307d11278e3SHarman Kalra /* Case: Repr port pattern -> Default TX rule -> LBK -> 308d11278e3SHarman Kalra * Pattern RX LBK rule hit -> Action: send to new pf_func 309d11278e3SHarman Kalra */ 310d11278e3SHarman Kalra if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) { 311d11278e3SHarman Kalra /* New pf_func corresponds to ESW + queue corresponding to rep_id */ 312d11278e3SHarman Kalra act_q = plt_zmalloc(sizeof(struct rte_flow_action_queue), 0); 313d11278e3SHarman Kalra if (!act_q) { 314d11278e3SHarman Kalra plt_err("Error allocation memory"); 315d11278e3SHarman Kalra return -ENOMEM; 316d11278e3SHarman Kalra } 317d11278e3SHarman Kalra act_q->index = rep_dev->rep_id; 318d11278e3SHarman Kalra 319d11278e3SHarman Kalra while (free_allocs[j] != 0) 320d11278e3SHarman Kalra j++; 321d11278e3SHarman Kalra free_allocs[j] = (uint64_t)act_q; 322d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE; 323d11278e3SHarman Kalra in_actions[i].conf = (struct rte_flow_action_queue *)act_q; 324d11278e3SHarman Kalra npc->rep_act_pf_func = rep_dev->parent_dev->npc.pf_func; 325d11278e3SHarman Kalra } else { 326d11278e3SHarman Kalra /* New pf_func corresponds to hw_func of representee */ 327d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID; 328d11278e3SHarman Kalra npc->rep_act_pf_func = rep_dev->hw_func; 329d11278e3SHarman Kalra *dst_pf_func = rep_dev->hw_func; 330d11278e3SHarman Kalra } 331d11278e3SHarman Kalra /* Additional action to strip the VLAN from packets received by LBK */ 332d11278e3SHarman Kalra i++; 333d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP; 334d11278e3SHarman Kalra goto done; 335d11278e3SHarman Kalra } 336d11278e3SHarman Kalra /* Case: Repd port pattern -> TX Rule with VLAN -> LBK -> Default RX LBK rule hit 337d11278e3SHarman Kalra * base on vlan, if packet goes to ESW or actual pf_func -> Action : 338d11278e3SHarman Kalra * act port_representor: send to ESW respective using 1<<8 | rep_id as tci value 339d11278e3SHarman Kalra * act represented_port: send to actual port using rep_id as tci value. 340d11278e3SHarman Kalra */ 341d11278e3SHarman Kalra /* Add RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN action */ 342d11278e3SHarman Kalra push_vlan = plt_zmalloc(sizeof(struct rte_flow_action_of_push_vlan), 0); 343d11278e3SHarman Kalra if (!push_vlan) { 344d11278e3SHarman Kalra plt_err("Error allocation memory"); 345d11278e3SHarman Kalra return -ENOMEM; 346d11278e3SHarman Kalra } 347d11278e3SHarman Kalra 348d11278e3SHarman Kalra while (free_allocs[j] != 0) 349d11278e3SHarman Kalra j++; 350d11278e3SHarman Kalra free_allocs[j] = (uint64_t)push_vlan; 351d11278e3SHarman Kalra push_vlan->ethertype = ntohs(ROC_ESWITCH_VLAN_TPID); 352d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT; 353d11278e3SHarman Kalra in_actions[i].conf = (struct rte_flow_action_of_push_vlan *)push_vlan; 354d11278e3SHarman Kalra i++; 355d11278e3SHarman Kalra 356d11278e3SHarman Kalra /* Add RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP action */ 357d11278e3SHarman Kalra vlan_pcp = plt_zmalloc(sizeof(struct rte_flow_action_of_set_vlan_pcp), 0); 358d11278e3SHarman Kalra if (!vlan_pcp) { 359d11278e3SHarman Kalra plt_err("Error allocation memory"); 360d11278e3SHarman Kalra return -ENOMEM; 361d11278e3SHarman Kalra } 362d11278e3SHarman Kalra 363d11278e3SHarman Kalra free_allocs[j + 1] = (uint64_t)vlan_pcp; 364d11278e3SHarman Kalra vlan_pcp->vlan_pcp = 0; 365d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT; 366d11278e3SHarman Kalra in_actions[i].conf = (struct rte_flow_action_of_set_vlan_pcp *)vlan_pcp; 367d11278e3SHarman Kalra i++; 368d11278e3SHarman Kalra 369d11278e3SHarman Kalra /* Add RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID action */ 370d11278e3SHarman Kalra vlan_vid = plt_zmalloc(sizeof(struct rte_flow_action_of_set_vlan_vid), 0); 371d11278e3SHarman Kalra if (!vlan_vid) { 372d11278e3SHarman Kalra plt_err("Error allocation memory"); 373d11278e3SHarman Kalra return -ENOMEM; 374d11278e3SHarman Kalra } 375d11278e3SHarman Kalra 376d11278e3SHarman Kalra free_allocs[j + 2] = (uint64_t)vlan_vid; 377d11278e3SHarman Kalra if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) 378d11278e3SHarman Kalra vlan_tci = rep_dev->rep_id | (1ULL << CNXK_ESWITCH_VFPF_SHIFT); 379d11278e3SHarman Kalra else 380d11278e3SHarman Kalra vlan_tci = rep_dev->rep_id; 381d11278e3SHarman Kalra vlan_vid->vlan_vid = ntohs(vlan_tci); 382d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT; 383d11278e3SHarman Kalra in_actions[i].conf = (struct rte_flow_action_of_set_vlan_vid *)vlan_vid; 384d11278e3SHarman Kalra 385d11278e3SHarman Kalra /* Change default channel to UCAST_CHAN (63) while sending */ 386d11278e3SHarman Kalra npc->rep_act_rep = true; 387d11278e3SHarman Kalra } else { 388d11278e3SHarman Kalra if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) { 389d11278e3SHarman Kalra /* Case: Pattern wire port -> Pattern RX rule-> 390d11278e3SHarman Kalra * Action: pf_func = ESW. queue = rep_id 391d11278e3SHarman Kalra */ 392d11278e3SHarman Kalra act_q = plt_zmalloc(sizeof(struct rte_flow_action_queue), 0); 393d11278e3SHarman Kalra if (!act_q) { 394d11278e3SHarman Kalra plt_err("Error allocation memory"); 395d11278e3SHarman Kalra return -ENOMEM; 396d11278e3SHarman Kalra } 397d11278e3SHarman Kalra while (free_allocs[j] != 0) 398d11278e3SHarman Kalra j++; 399d11278e3SHarman Kalra free_allocs[j] = (uint64_t)act_q; 400d11278e3SHarman Kalra act_q->index = rep_dev->rep_id; 401d11278e3SHarman Kalra 402d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE; 403d11278e3SHarman Kalra in_actions[i].conf = (struct rte_flow_action_queue *)act_q; 404d11278e3SHarman Kalra npc->rep_act_pf_func = rep_dev->parent_dev->npc.pf_func; 405d11278e3SHarman Kalra } else { 406d11278e3SHarman Kalra /* Case: Pattern wire port -> Pattern RX rule-> 407d11278e3SHarman Kalra * Action: Receive at actual hw_func 408d11278e3SHarman Kalra */ 409d11278e3SHarman Kalra in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID; 410d11278e3SHarman Kalra npc->rep_act_pf_func = rep_dev->hw_func; 411d11278e3SHarman Kalra *dst_pf_func = rep_dev->hw_func; 412c2f3e9e7SHarman Kalra 413c2f3e9e7SHarman Kalra /* Append a mark action - needed to identify the flow */ 414c2f3e9e7SHarman Kalra rc = append_mark_action(in_actions, has_tunnel_pattern, free_allocs, &i); 415c2f3e9e7SHarman Kalra if (rc) 416c2f3e9e7SHarman Kalra return rc; 417*0981a22eSHarman Kalra /* Append RSS action if representee has RSS enabled */ 418*0981a22eSHarman Kalra if (rep_dev->nb_rxq > 1) { 419*0981a22eSHarman Kalra /* PF can install rule for only its VF acting as representee */ 420*0981a22eSHarman Kalra if (rep_dev->hw_func && 421*0981a22eSHarman Kalra roc_eswitch_is_repte_pfs_vf(rep_dev->hw_func, 422*0981a22eSHarman Kalra roc_nix_get_pf_func(npc->roc_nix))) { 423*0981a22eSHarman Kalra rc = append_rss_action(dev, in_actions, rep_dev->nb_rxq, 424*0981a22eSHarman Kalra flowkey_cfg, free_allocs, 425*0981a22eSHarman Kalra rep_dev->hw_func, &i); 426*0981a22eSHarman Kalra if (rc) 427*0981a22eSHarman Kalra return rc; 428*0981a22eSHarman Kalra } 429*0981a22eSHarman Kalra } 430d11278e3SHarman Kalra } 431d11278e3SHarman Kalra } 432d11278e3SHarman Kalra done: 433d11278e3SHarman Kalra *act_cnt = i; 434d11278e3SHarman Kalra 435d11278e3SHarman Kalra return 0; 436d11278e3SHarman Kalra } 437d11278e3SHarman Kalra 438d11278e3SHarman Kalra static int 439c1ae225eSHarman Kalra representor_portid_action(struct roc_npc_action *in_actions, struct rte_eth_dev *portid_eth_dev, 440d11278e3SHarman Kalra uint16_t *dst_pf_func, uint8_t has_tunnel_pattern, uint64_t *free_allocs, 441d11278e3SHarman Kalra int *act_cnt) 442c1ae225eSHarman Kalra { 443c1ae225eSHarman Kalra struct rte_eth_dev *rep_eth_dev = portid_eth_dev; 444c1ae225eSHarman Kalra struct cnxk_rep_dev *rep_dev; 445c1ae225eSHarman Kalra /* For inserting an action in the list */ 446c2f3e9e7SHarman Kalra int i = *act_cnt, rc; 447c1ae225eSHarman Kalra 448c1ae225eSHarman Kalra rep_dev = cnxk_rep_pmd_priv(rep_eth_dev); 449d11278e3SHarman Kalra 450c1ae225eSHarman Kalra *dst_pf_func = rep_dev->hw_func; 451c1ae225eSHarman Kalra 452c2f3e9e7SHarman Kalra rc = append_mark_action(in_actions, has_tunnel_pattern, free_allocs, &i); 453c2f3e9e7SHarman Kalra if (rc) 454c2f3e9e7SHarman Kalra return rc; 455c1ae225eSHarman Kalra 456c1ae225eSHarman Kalra *act_cnt = i; 457c2f3e9e7SHarman Kalra plt_rep_dbg("Rep port %d ID %d rep_dev->hw_func 0x%x", rep_dev->port_id, rep_dev->rep_id, 458c2f3e9e7SHarman Kalra rep_dev->hw_func); 459c1ae225eSHarman Kalra 460c1ae225eSHarman Kalra return 0; 461c1ae225eSHarman Kalra } 462c1ae225eSHarman Kalra 463c1ae225eSHarman Kalra static int 464795ac238SJerin Jacob cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 465b7eb0e0cSSatheesh Paul const struct rte_flow_action actions[], struct roc_npc_action in_actions[], 466dd23ff70SSatheesh Paul struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg, 467d11278e3SHarman Kalra uint16_t *dst_pf_func, uint8_t has_tunnel_pattern, bool is_rep, 468d11278e3SHarman Kalra uint8_t rep_pattern, uint64_t *free_allocs) 469795ac238SJerin Jacob { 470795ac238SJerin Jacob struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 47147f40516SSatheesh Paul const struct rte_flow_action_queue *act_q = NULL; 472a05a8e40SIvan Malov const struct rte_flow_action_ethdev *act_ethdev; 473dd23ff70SSatheesh Paul const struct rte_flow_action_sample *act_sample; 474795ac238SJerin Jacob const struct rte_flow_action_port_id *port_act; 475795ac238SJerin Jacob struct rte_eth_dev *portid_eth_dev; 476795ac238SJerin Jacob char if_name[RTE_ETH_NAME_MAX_LEN]; 477795ac238SJerin Jacob struct cnxk_eth_dev *hw_dst; 478795ac238SJerin Jacob struct roc_npc *roc_npc_dst; 47947f40516SSatheesh Paul bool is_vf_action = false; 480795ac238SJerin Jacob int i = 0, rc = 0; 481795ac238SJerin Jacob int rq; 482795ac238SJerin Jacob 483795ac238SJerin Jacob for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { 484795ac238SJerin Jacob switch (actions->type) { 485795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_VOID: 486795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID; 487795ac238SJerin Jacob break; 488795ac238SJerin Jacob 489795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_MARK: 490795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK; 491795ac238SJerin Jacob in_actions[i].conf = actions->conf; 492795ac238SJerin Jacob break; 493795ac238SJerin Jacob 494795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_FLAG: 495795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG; 496795ac238SJerin Jacob break; 497795ac238SJerin Jacob 498795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_COUNT: 499795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT; 500795ac238SJerin Jacob break; 501795ac238SJerin Jacob 502795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_DROP: 503795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP; 504795ac238SJerin Jacob break; 505795ac238SJerin Jacob 506795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_PF: 507795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_PF; 508795ac238SJerin Jacob break; 509795ac238SJerin Jacob 510795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_VF: 511795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_VF; 512795ac238SJerin Jacob in_actions[i].conf = actions->conf; 51347f40516SSatheesh Paul is_vf_action = true; 514795ac238SJerin Jacob break; 515795ac238SJerin Jacob 516a05a8e40SIvan Malov case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 517c1ae225eSHarman Kalra case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 518d11278e3SHarman Kalra in_actions[i].conf = actions->conf; 519d11278e3SHarman Kalra act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf; 520d11278e3SHarman Kalra if (rte_eth_dev_get_name_by_port(act_ethdev->port_id, if_name)) { 521d11278e3SHarman Kalra plt_err("Name not found for output port id"); 522d11278e3SHarman Kalra goto err_exit; 523d11278e3SHarman Kalra } 524d11278e3SHarman Kalra portid_eth_dev = rte_eth_dev_allocated(if_name); 525d11278e3SHarman Kalra if (!portid_eth_dev) { 526d11278e3SHarman Kalra plt_err("eth_dev not found for output port id"); 527d11278e3SHarman Kalra goto err_exit; 528d11278e3SHarman Kalra } 529d11278e3SHarman Kalra 530d11278e3SHarman Kalra plt_rep_dbg("Rule installed by port %d if_name %s act_ethdev->port_id %d", 531d11278e3SHarman Kalra eth_dev->data->port_id, if_name, act_ethdev->port_id); 532d11278e3SHarman Kalra if (cnxk_ethdev_is_representor(if_name)) { 533d11278e3SHarman Kalra if (representor_rep_portid_action(in_actions, eth_dev, 534*0981a22eSHarman Kalra portid_eth_dev, actions->type, rep_pattern, 535*0981a22eSHarman Kalra dst_pf_func, is_rep, has_tunnel_pattern, 536*0981a22eSHarman Kalra free_allocs, &i, flowkey_cfg)) { 537d11278e3SHarman Kalra plt_err("Representor port action set failed"); 538d11278e3SHarman Kalra goto err_exit; 539d11278e3SHarman Kalra } 540d11278e3SHarman Kalra } else { 541d11278e3SHarman Kalra if (actions->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) 542d11278e3SHarman Kalra continue; 543d11278e3SHarman Kalra /* Normal port as represented_port as action not supported*/ 544d11278e3SHarman Kalra return -ENOTSUP; 545d11278e3SHarman Kalra } 546d11278e3SHarman Kalra break; 547795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_PORT_ID: 548d11278e3SHarman Kalra /* No port ID action on representor ethdevs */ 549d11278e3SHarman Kalra if (is_rep) 550d11278e3SHarman Kalra continue; 551795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID; 552795ac238SJerin Jacob in_actions[i].conf = actions->conf; 553d11278e3SHarman Kalra act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf; 554d11278e3SHarman Kalra port_act = (const struct rte_flow_action_port_id *)actions->conf; 555a05a8e40SIvan Malov if (rte_eth_dev_get_name_by_port( 556a05a8e40SIvan Malov actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ? 557d11278e3SHarman Kalra act_ethdev->port_id : 558d11278e3SHarman Kalra port_act->id, 559d11278e3SHarman Kalra if_name)) { 560795ac238SJerin Jacob plt_err("Name not found for output port id"); 561795ac238SJerin Jacob goto err_exit; 562795ac238SJerin Jacob } 563795ac238SJerin Jacob portid_eth_dev = rte_eth_dev_allocated(if_name); 564795ac238SJerin Jacob if (!portid_eth_dev) { 565795ac238SJerin Jacob plt_err("eth_dev not found for output port id"); 566795ac238SJerin Jacob goto err_exit; 567795ac238SJerin Jacob } 568c1ae225eSHarman Kalra 569c1ae225eSHarman Kalra if (cnxk_ethdev_is_representor(if_name)) { 570c1ae225eSHarman Kalra plt_rep_dbg("Representor port %d act port %d", port_act->id, 571c1ae225eSHarman Kalra act_ethdev->port_id); 572c1ae225eSHarman Kalra if (representor_portid_action(in_actions, portid_eth_dev, 573c1ae225eSHarman Kalra dst_pf_func, has_tunnel_pattern, 574d11278e3SHarman Kalra free_allocs, &i)) { 575c1ae225eSHarman Kalra plt_err("Representor port action set failed"); 576c1ae225eSHarman Kalra goto err_exit; 577c1ae225eSHarman Kalra } 578c1ae225eSHarman Kalra } else { 579795ac238SJerin Jacob if (strcmp(portid_eth_dev->device->driver->name, 580795ac238SJerin Jacob eth_dev->device->driver->name) != 0) { 581795ac238SJerin Jacob plt_err("Output port not under same driver"); 582795ac238SJerin Jacob goto err_exit; 583795ac238SJerin Jacob } 584c1ae225eSHarman Kalra 585795ac238SJerin Jacob hw_dst = portid_eth_dev->data->dev_private; 586795ac238SJerin Jacob roc_npc_dst = &hw_dst->npc; 587b7eb0e0cSSatheesh Paul *dst_pf_func = roc_npc_dst->pf_func; 588c1ae225eSHarman Kalra } 589795ac238SJerin Jacob break; 590795ac238SJerin Jacob 591795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_QUEUE: 59247f40516SSatheesh Paul act_q = (const struct rte_flow_action_queue *)actions->conf; 593795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE; 594795ac238SJerin Jacob in_actions[i].conf = actions->conf; 595795ac238SJerin Jacob break; 596795ac238SJerin Jacob 597795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_RSS: 598d11278e3SHarman Kalra /* No RSS action on representor ethdevs */ 599d11278e3SHarman Kalra if (is_rep) 600d11278e3SHarman Kalra continue; 601795ac238SJerin Jacob rc = npc_rss_action_validate(eth_dev, attr, actions); 602795ac238SJerin Jacob if (rc) 603795ac238SJerin Jacob goto err_exit; 604*0981a22eSHarman Kalra 605795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS; 606795ac238SJerin Jacob in_actions[i].conf = actions->conf; 607752ce2f3SKiran Kumar K npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg, 608752ce2f3SKiran Kumar K eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf); 609795ac238SJerin Jacob break; 610795ac238SJerin Jacob 611795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_SECURITY: 612795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC; 6138efa348eSKiran Kumar K in_actions[i].conf = actions->conf; 614795ac238SJerin Jacob break; 615795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: 616795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP; 617795ac238SJerin Jacob break; 618795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: 619795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT; 620795ac238SJerin Jacob in_actions[i].conf = actions->conf; 621795ac238SJerin Jacob break; 622795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: 623795ac238SJerin Jacob in_actions[i].type = 624795ac238SJerin Jacob ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT; 625795ac238SJerin Jacob in_actions[i].conf = actions->conf; 626795ac238SJerin Jacob break; 627795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: 628795ac238SJerin Jacob in_actions[i].type = 629795ac238SJerin Jacob ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT; 630795ac238SJerin Jacob in_actions[i].conf = actions->conf; 631795ac238SJerin Jacob break; 632795ac238SJerin Jacob case RTE_FLOW_ACTION_TYPE_METER: 633795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_METER; 634795ac238SJerin Jacob in_actions[i].conf = actions->conf; 635795ac238SJerin Jacob break; 636a4477550SAnkur Dwivedi case RTE_FLOW_ACTION_TYPE_AGE: 637a4477550SAnkur Dwivedi in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE; 638a4477550SAnkur Dwivedi in_actions[i].conf = actions->conf; 639a4477550SAnkur Dwivedi break; 640dd23ff70SSatheesh Paul case RTE_FLOW_ACTION_TYPE_SAMPLE: 641dd23ff70SSatheesh Paul act_sample = actions->conf; 642dd23ff70SSatheesh Paul in_sample_actions->ratio = act_sample->ratio; 643dd23ff70SSatheesh Paul rc = roc_npc_parse_sample_subaction(eth_dev, act_sample->actions, 644dd23ff70SSatheesh Paul in_sample_actions); 645dd23ff70SSatheesh Paul if (rc) { 646dd23ff70SSatheesh Paul plt_err("Sample subaction parsing failed."); 647dd23ff70SSatheesh Paul goto err_exit; 648dd23ff70SSatheesh Paul } 649dd23ff70SSatheesh Paul 650dd23ff70SSatheesh Paul in_actions[i].type = ROC_NPC_ACTION_TYPE_SAMPLE; 651dd23ff70SSatheesh Paul in_actions[i].conf = in_sample_actions; 652dd23ff70SSatheesh Paul break; 653c1ae225eSHarman Kalra case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: 654c1ae225eSHarman Kalra continue; 655795ac238SJerin Jacob default: 656dd23ff70SSatheesh Paul plt_npc_dbg("Action is not supported = %d", actions->type); 657795ac238SJerin Jacob goto err_exit; 658795ac238SJerin Jacob } 659795ac238SJerin Jacob i++; 660795ac238SJerin Jacob } 66147f40516SSatheesh Paul 66247f40516SSatheesh Paul if (!is_vf_action && act_q) { 66347f40516SSatheesh Paul rq = act_q->index; 66447f40516SSatheesh Paul if (rq >= eth_dev->data->nb_rx_queues) { 66547f40516SSatheesh Paul plt_npc_dbg("Invalid queue index"); 66647f40516SSatheesh Paul goto err_exit; 66747f40516SSatheesh Paul } 66847f40516SSatheesh Paul } 669795ac238SJerin Jacob in_actions[i].type = ROC_NPC_ACTION_TYPE_END; 670795ac238SJerin Jacob return 0; 671795ac238SJerin Jacob 672795ac238SJerin Jacob err_exit: 673795ac238SJerin Jacob return -EINVAL; 674795ac238SJerin Jacob } 675795ac238SJerin Jacob 676795ac238SJerin Jacob static int 677c1ae225eSHarman Kalra cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern[], 678d11278e3SHarman Kalra struct roc_npc_item_info in_pattern[], uint8_t *has_tunnel_pattern, bool is_rep, 679d11278e3SHarman Kalra uint8_t *rep_pattern, uint64_t *free_allocs) 680795ac238SJerin Jacob { 68100701e71SKiran Kumar K const struct rte_flow_item_ethdev *rep_eth_dev; 68200701e71SKiran Kumar K struct rte_eth_dev *portid_eth_dev; 68300701e71SKiran Kumar K char if_name[RTE_ETH_NAME_MAX_LEN]; 68400701e71SKiran Kumar K struct cnxk_eth_dev *hw_dst; 685d11278e3SHarman Kalra struct cnxk_rep_dev *rdev; 686d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 687d11278e3SHarman Kalra struct roc_npc *npc; 688d11278e3SHarman Kalra int i = 0, j = 0; 689d11278e3SHarman Kalra 690d11278e3SHarman Kalra if (!is_rep) { 691d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 692d11278e3SHarman Kalra npc = &dev->npc; 693d11278e3SHarman Kalra } else { 694d11278e3SHarman Kalra rdev = cnxk_rep_pmd_priv(eth_dev); 695d11278e3SHarman Kalra npc = &rdev->parent_dev->npc; 696d11278e3SHarman Kalra 697d11278e3SHarman Kalra npc->rep_npc = npc; 698d11278e3SHarman Kalra npc->rep_port_id = rdev->port_id; 699d11278e3SHarman Kalra npc->rep_pf_func = rdev->hw_func; 700d11278e3SHarman Kalra } 701795ac238SJerin Jacob 702795ac238SJerin Jacob while (pattern->type != RTE_FLOW_ITEM_TYPE_END) { 703795ac238SJerin Jacob in_pattern[i].spec = pattern->spec; 704795ac238SJerin Jacob in_pattern[i].last = pattern->last; 705795ac238SJerin Jacob in_pattern[i].mask = pattern->mask; 706795ac238SJerin Jacob in_pattern[i].type = term[pattern->type].item_type; 707795ac238SJerin Jacob in_pattern[i].size = term[pattern->type].item_size; 708d11278e3SHarman Kalra if (pattern->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT || 709d11278e3SHarman Kalra pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) { 71000701e71SKiran Kumar K rep_eth_dev = (const struct rte_flow_item_ethdev *)pattern->spec; 71100701e71SKiran Kumar K if (rte_eth_dev_get_name_by_port(rep_eth_dev->port_id, if_name)) { 71200701e71SKiran Kumar K plt_err("Name not found for output port id"); 713c1ae225eSHarman Kalra goto fail; 71400701e71SKiran Kumar K } 71500701e71SKiran Kumar K portid_eth_dev = rte_eth_dev_allocated(if_name); 71600701e71SKiran Kumar K if (!portid_eth_dev) { 71700701e71SKiran Kumar K plt_err("eth_dev not found for output port id"); 718c1ae225eSHarman Kalra goto fail; 71900701e71SKiran Kumar K } 720d11278e3SHarman Kalra *rep_pattern = pattern->type; 721c1ae225eSHarman Kalra if (cnxk_ethdev_is_representor(if_name)) { 722c1ae225eSHarman Kalra /* Case where represented port not part of same 723c1ae225eSHarman Kalra * app and represented by a representor port. 724c1ae225eSHarman Kalra */ 725c1ae225eSHarman Kalra struct cnxk_rep_dev *rep_dev; 726c1ae225eSHarman Kalra struct cnxk_eswitch_dev *eswitch_dev; 727c1ae225eSHarman Kalra 728c1ae225eSHarman Kalra rep_dev = cnxk_rep_pmd_priv(portid_eth_dev); 729c1ae225eSHarman Kalra eswitch_dev = rep_dev->parent_dev; 730d11278e3SHarman Kalra npc->rep_npc = &eswitch_dev->npc; 731d11278e3SHarman Kalra npc->rep_port_id = rep_eth_dev->port_id; 732d11278e3SHarman Kalra npc->rep_pf_func = rep_dev->hw_func; 733d11278e3SHarman Kalra 734d11278e3SHarman Kalra if (pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) { 735d11278e3SHarman Kalra struct rte_flow_item_vlan *vlan; 736d11278e3SHarman Kalra 737d11278e3SHarman Kalra npc->rep_pf_func = eswitch_dev->npc.pf_func; 738d11278e3SHarman Kalra /* Add VLAN pattern corresponding to rep_id */ 739d11278e3SHarman Kalra i++; 740d11278e3SHarman Kalra vlan = plt_zmalloc(sizeof(struct rte_flow_item_vlan), 0); 741d11278e3SHarman Kalra if (!vlan) { 742d11278e3SHarman Kalra plt_err("error allocation memory"); 743d11278e3SHarman Kalra return -ENOMEM; 744d11278e3SHarman Kalra } 745d11278e3SHarman Kalra 746d11278e3SHarman Kalra while (free_allocs[j] != 0) 747d11278e3SHarman Kalra j++; 748d11278e3SHarman Kalra free_allocs[j] = (uint64_t)vlan; 749d11278e3SHarman Kalra 750d11278e3SHarman Kalra npc->rep_rx_channel = ROC_ESWITCH_LBK_CHAN; 751d11278e3SHarman Kalra vlan->hdr.vlan_tci = RTE_BE16(rep_dev->rep_id); 752d11278e3SHarman Kalra in_pattern[i].spec = (struct rte_flow_item_vlan *)vlan; 753d11278e3SHarman Kalra in_pattern[i].last = NULL; 754d11278e3SHarman Kalra in_pattern[i].mask = &rte_flow_item_vlan_mask; 755d11278e3SHarman Kalra in_pattern[i].type = 756d11278e3SHarman Kalra term[RTE_FLOW_ITEM_TYPE_VLAN].item_type; 757d11278e3SHarman Kalra in_pattern[i].size = 758d11278e3SHarman Kalra term[RTE_FLOW_ITEM_TYPE_VLAN].item_size; 759d11278e3SHarman Kalra } 760d11278e3SHarman Kalra *rep_pattern |= 1 << IS_REP_BIT; 761c1ae225eSHarman Kalra plt_rep_dbg("Represented port %d act port %d rep_dev->hw_func 0x%x", 762c1ae225eSHarman Kalra rep_eth_dev->port_id, eth_dev->data->port_id, 763c1ae225eSHarman Kalra rep_dev->hw_func); 764c1ae225eSHarman Kalra } else { 765d11278e3SHarman Kalra if (strcmp(portid_eth_dev->device->driver->name, 766d11278e3SHarman Kalra eth_dev->device->driver->name) != 0) { 767d11278e3SHarman Kalra plt_err("Output port not under same driver"); 768d11278e3SHarman Kalra goto fail; 769d11278e3SHarman Kalra } 770d11278e3SHarman Kalra /* Normal port as port_representor pattern can't be supported */ 771d11278e3SHarman Kalra if (pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) 772d11278e3SHarman Kalra return -ENOTSUP; 773c1ae225eSHarman Kalra /* Case where represented port part of same app 774c1ae225eSHarman Kalra * as PF. 775c1ae225eSHarman Kalra */ 77600701e71SKiran Kumar K hw_dst = portid_eth_dev->data->dev_private; 777d11278e3SHarman Kalra npc->rep_npc = &hw_dst->npc; 778d11278e3SHarman Kalra npc->rep_port_id = rep_eth_dev->port_id; 779d11278e3SHarman Kalra npc->rep_pf_func = hw_dst->npc.pf_func; 78000701e71SKiran Kumar K } 781c1ae225eSHarman Kalra } 782c1ae225eSHarman Kalra 783c1ae225eSHarman Kalra if (pattern->type == RTE_FLOW_ITEM_TYPE_VXLAN || 784c1ae225eSHarman Kalra pattern->type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || 785c1ae225eSHarman Kalra pattern->type == RTE_FLOW_ITEM_TYPE_GRE) 786c1ae225eSHarman Kalra *has_tunnel_pattern = pattern->type; 787c1ae225eSHarman Kalra 788795ac238SJerin Jacob pattern++; 789795ac238SJerin Jacob i++; 790795ac238SJerin Jacob } 791795ac238SJerin Jacob in_pattern[i].type = ROC_NPC_ITEM_TYPE_END; 792c1ae225eSHarman Kalra return 0; 793c1ae225eSHarman Kalra fail: 794c1ae225eSHarman Kalra return -EINVAL; 795c1ae225eSHarman Kalra } 796c1ae225eSHarman Kalra 797c1ae225eSHarman Kalra static int 798c1ae225eSHarman Kalra cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 799c1ae225eSHarman Kalra const struct rte_flow_item pattern[], const struct rte_flow_action actions[], 800c1ae225eSHarman Kalra struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[], 801c1ae225eSHarman Kalra struct roc_npc_action in_actions[], 802c1ae225eSHarman Kalra struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg, 803d11278e3SHarman Kalra uint16_t *dst_pf_func, bool is_rep, uint64_t *free_allocs) 804c1ae225eSHarman Kalra { 805d11278e3SHarman Kalra uint8_t has_tunnel_pattern = 0, rep_pattern = 0; 806c1ae225eSHarman Kalra int rc; 807c1ae225eSHarman Kalra 808c1ae225eSHarman Kalra in_attr->priority = attr->priority; 809c1ae225eSHarman Kalra in_attr->ingress = attr->ingress; 810c1ae225eSHarman Kalra in_attr->egress = attr->egress; 811c1ae225eSHarman Kalra 812d11278e3SHarman Kalra rc = cnxk_map_pattern(eth_dev, pattern, in_pattern, &has_tunnel_pattern, is_rep, 813d11278e3SHarman Kalra &rep_pattern, free_allocs); 814c1ae225eSHarman Kalra if (rc) { 815c1ae225eSHarman Kalra plt_err("Failed to map pattern list"); 816c1ae225eSHarman Kalra return rc; 817c1ae225eSHarman Kalra } 818795ac238SJerin Jacob 819d11278e3SHarman Kalra if (attr->transfer) { 820d11278e3SHarman Kalra /* rep_pattern is used to identify if RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT 821d11278e3SHarman Kalra * OR RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR is defined + if pattern's portid is 822d11278e3SHarman Kalra * normal port or representor port. 823d11278e3SHarman Kalra * For normal port_id, rep_pattern = pattern-> type 824d11278e3SHarman Kalra * For representor port, rep_pattern = pattern-> type | 1 << IS_REP_BIT 825d11278e3SHarman Kalra */ 826d11278e3SHarman Kalra if (is_rep || rep_pattern) { 827d11278e3SHarman Kalra if (rep_pattern == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT || 828d11278e3SHarman Kalra ((rep_pattern & 0x7f) == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR)) 829d11278e3SHarman Kalra /* If pattern is port_representor or pattern has normal port as 830d11278e3SHarman Kalra * represented port, install ingress rule. 831d11278e3SHarman Kalra */ 832d11278e3SHarman Kalra in_attr->ingress = attr->transfer; 833d11278e3SHarman Kalra else 834d11278e3SHarman Kalra in_attr->egress = attr->transfer; 835d11278e3SHarman Kalra } else { 836d11278e3SHarman Kalra in_attr->ingress = attr->transfer; 837d11278e3SHarman Kalra } 838795ac238SJerin Jacob } 839795ac238SJerin Jacob 840d11278e3SHarman Kalra return cnxk_map_actions(eth_dev, attr, actions, in_actions, in_sample_actions, flowkey_cfg, 841d11278e3SHarman Kalra dst_pf_func, has_tunnel_pattern, is_rep, rep_pattern, free_allocs); 842d11278e3SHarman Kalra } 843d11278e3SHarman Kalra 844d11278e3SHarman Kalra int 845d11278e3SHarman Kalra cnxk_flow_validate_common(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 846d11278e3SHarman Kalra const struct rte_flow_item pattern[], 847d11278e3SHarman Kalra const struct rte_flow_action actions[], struct rte_flow_error *error, 848d11278e3SHarman Kalra bool is_rep) 849795ac238SJerin Jacob { 850795ac238SJerin Jacob struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1]; 851795ac238SJerin Jacob struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT]; 852dd23ff70SSatheesh Paul struct roc_npc_action_sample in_sample_action; 853d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 854795ac238SJerin Jacob struct roc_npc_attr in_attr; 855d11278e3SHarman Kalra uint64_t *free_allocs, sz; 856d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 857795ac238SJerin Jacob struct roc_npc_flow flow; 858795ac238SJerin Jacob uint32_t flowkey_cfg = 0; 859b7eb0e0cSSatheesh Paul uint16_t dst_pf_func = 0; 860d11278e3SHarman Kalra struct roc_npc *npc; 861d11278e3SHarman Kalra int rc, j; 862795ac238SJerin Jacob 863d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 864d11278e3SHarman Kalra if (!is_rep) { 865d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 866d11278e3SHarman Kalra npc = &dev->npc; 86714598b31SAkhil Goyal /* Skip flow validation for MACsec. */ 86814598b31SAkhil Goyal if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY && 86914598b31SAkhil Goyal cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) 87014598b31SAkhil Goyal return 0; 871d11278e3SHarman Kalra } else { 872d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 873d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 874d11278e3SHarman Kalra } 87514598b31SAkhil Goyal 876795ac238SJerin Jacob memset(&flow, 0, sizeof(flow)); 877dd23ff70SSatheesh Paul memset(&in_sample_action, 0, sizeof(in_sample_action)); 878b7f7e748SKiran Kumar K flow.is_validate = true; 879795ac238SJerin Jacob 880d11278e3SHarman Kalra sz = ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1; 881d11278e3SHarman Kalra free_allocs = plt_zmalloc(sz * sizeof(uint64_t), 0); 882d11278e3SHarman Kalra if (!free_allocs) { 883d11278e3SHarman Kalra rte_flow_error_set(error, -ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, 884d11278e3SHarman Kalra "Failed to map flow data"); 885d11278e3SHarman Kalra return -ENOMEM; 886d11278e3SHarman Kalra } 887b7f7e748SKiran Kumar K rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions, 888d11278e3SHarman Kalra &in_sample_action, &flowkey_cfg, &dst_pf_func, is_rep, free_allocs); 889795ac238SJerin Jacob if (rc) { 890b7f7e748SKiran Kumar K rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, 891b7f7e748SKiran Kumar K "Failed to map flow data"); 892d11278e3SHarman Kalra goto clean; 893795ac238SJerin Jacob } 894795ac238SJerin Jacob 895c8647cd7SSatheesh Paul rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow); 896c8647cd7SSatheesh Paul 897c8647cd7SSatheesh Paul if (rc) { 898c8647cd7SSatheesh Paul rte_flow_error_set(error, 0, rc, NULL, 899c8647cd7SSatheesh Paul "Flow validation failed"); 900d11278e3SHarman Kalra goto clean; 901d11278e3SHarman Kalra } 902d11278e3SHarman Kalra clean: 903d11278e3SHarman Kalra /* Freeing the allocations done for additional patterns/actions */ 904d11278e3SHarman Kalra for (j = 0; (j < (int)sz) && free_allocs[j]; j++) 905d11278e3SHarman Kalra plt_free((void *)free_allocs[j]); 906d11278e3SHarman Kalra plt_free(free_allocs); 907d11278e3SHarman Kalra 908c8647cd7SSatheesh Paul return rc; 909c8647cd7SSatheesh Paul } 910d11278e3SHarman Kalra 911d11278e3SHarman Kalra static int 912d11278e3SHarman Kalra cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 913d11278e3SHarman Kalra const struct rte_flow_item pattern[], const struct rte_flow_action actions[], 914d11278e3SHarman Kalra struct rte_flow_error *error) 915d11278e3SHarman Kalra { 916d11278e3SHarman Kalra return cnxk_flow_validate_common(eth_dev, attr, pattern, actions, error, false); 917795ac238SJerin Jacob } 918795ac238SJerin Jacob 919795ac238SJerin Jacob struct roc_npc_flow * 920d11278e3SHarman Kalra cnxk_flow_create_common(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 921795ac238SJerin Jacob const struct rte_flow_item pattern[], 922d11278e3SHarman Kalra const struct rte_flow_action actions[], struct rte_flow_error *error, 923d11278e3SHarman Kalra bool is_rep) 924795ac238SJerin Jacob { 925*0981a22eSHarman Kalra struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1] = {0}; 926*0981a22eSHarman Kalra struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT] = {0}; 927dd23ff70SSatheesh Paul struct roc_npc_action_sample in_sample_action; 928d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev = NULL; 929d11278e3SHarman Kalra struct roc_npc_flow *flow = NULL; 930d11278e3SHarman Kalra struct cnxk_eth_dev *dev = NULL; 931795ac238SJerin Jacob struct roc_npc_attr in_attr; 932d11278e3SHarman Kalra uint64_t *free_allocs, sz; 933b7eb0e0cSSatheesh Paul uint16_t dst_pf_func = 0; 934d11278e3SHarman Kalra struct roc_npc *npc; 935795ac238SJerin Jacob int errcode = 0; 936d11278e3SHarman Kalra int rc, j; 937795ac238SJerin Jacob 938d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 939d11278e3SHarman Kalra if (!is_rep) { 940d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 941d11278e3SHarman Kalra npc = &dev->npc; 942d11278e3SHarman Kalra } else { 943d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 944d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 945d11278e3SHarman Kalra } 946d11278e3SHarman Kalra 947d11278e3SHarman Kalra sz = ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1; 948d11278e3SHarman Kalra free_allocs = plt_zmalloc(sz * sizeof(uint64_t), 0); 949d11278e3SHarman Kalra if (!free_allocs) { 950d11278e3SHarman Kalra rte_flow_error_set(error, -ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, 951d11278e3SHarman Kalra "Failed to map flow data"); 952d11278e3SHarman Kalra return NULL; 953d11278e3SHarman Kalra } 954dd23ff70SSatheesh Paul memset(&in_sample_action, 0, sizeof(in_sample_action)); 955c1ae225eSHarman Kalra memset(&in_attr, 0, sizeof(struct roc_npc_attr)); 956b7eb0e0cSSatheesh Paul rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions, 957d11278e3SHarman Kalra &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func, is_rep, 958d11278e3SHarman Kalra free_allocs); 959795ac238SJerin Jacob if (rc) { 960d11278e3SHarman Kalra rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, 961b7eb0e0cSSatheesh Paul "Failed to map flow data"); 962d11278e3SHarman Kalra goto clean; 963795ac238SJerin Jacob } 964795ac238SJerin Jacob 965b7eb0e0cSSatheesh Paul flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, dst_pf_func, &errcode); 966795ac238SJerin Jacob if (errcode != 0) { 967b7eb0e0cSSatheesh Paul rte_flow_error_set(error, errcode, errcode, NULL, roc_error_msg_get(errcode)); 968d11278e3SHarman Kalra goto clean; 969795ac238SJerin Jacob } 970795ac238SJerin Jacob 971d11278e3SHarman Kalra clean: 972d11278e3SHarman Kalra /* Freeing the allocations done for additional patterns/actions */ 973d11278e3SHarman Kalra for (j = 0; (j < (int)sz) && free_allocs[j]; j++) 974d11278e3SHarman Kalra plt_free((void *)free_allocs[j]); 975d11278e3SHarman Kalra plt_free(free_allocs); 976d11278e3SHarman Kalra 977795ac238SJerin Jacob return flow; 978795ac238SJerin Jacob } 979795ac238SJerin Jacob 980d11278e3SHarman Kalra struct roc_npc_flow * 981d11278e3SHarman Kalra cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, 982d11278e3SHarman Kalra const struct rte_flow_item pattern[], const struct rte_flow_action actions[], 983d11278e3SHarman Kalra struct rte_flow_error *error) 984d11278e3SHarman Kalra { 985d11278e3SHarman Kalra return cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false); 986d11278e3SHarman Kalra } 987d11278e3SHarman Kalra 988d11278e3SHarman Kalra int 989d11278e3SHarman Kalra cnxk_flow_destroy_common(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow, 990d11278e3SHarman Kalra struct rte_flow_error *error, bool is_rep) 991d11278e3SHarman Kalra { 992d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 993d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 994d11278e3SHarman Kalra struct roc_npc *npc; 995d11278e3SHarman Kalra int rc; 996d11278e3SHarman Kalra 997d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 998d11278e3SHarman Kalra if (!is_rep) { 999d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 1000d11278e3SHarman Kalra npc = &dev->npc; 1001d11278e3SHarman Kalra } else { 1002d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 1003d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 1004d11278e3SHarman Kalra } 1005d11278e3SHarman Kalra 1006d11278e3SHarman Kalra rc = roc_npc_flow_destroy(npc, flow); 1007d11278e3SHarman Kalra if (rc) 1008d11278e3SHarman Kalra rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1009d11278e3SHarman Kalra "Flow Destroy failed"); 1010d11278e3SHarman Kalra return rc; 1011d11278e3SHarman Kalra } 1012d11278e3SHarman Kalra 1013795ac238SJerin Jacob int 1014795ac238SJerin Jacob cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow, 1015795ac238SJerin Jacob struct rte_flow_error *error) 1016795ac238SJerin Jacob { 1017d11278e3SHarman Kalra return cnxk_flow_destroy_common(eth_dev, flow, error, false); 1018795ac238SJerin Jacob } 1019795ac238SJerin Jacob 1020d11278e3SHarman Kalra int 1021d11278e3SHarman Kalra cnxk_flow_flush_common(struct rte_eth_dev *eth_dev, struct rte_flow_error *error, bool is_rep) 1022795ac238SJerin Jacob { 1023d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 1024d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 1025d11278e3SHarman Kalra struct roc_npc *npc; 1026795ac238SJerin Jacob int rc; 1027795ac238SJerin Jacob 1028d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 1029d11278e3SHarman Kalra if (!is_rep) { 1030d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 1031d11278e3SHarman Kalra npc = &dev->npc; 1032d11278e3SHarman Kalra } else { 1033d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 1034d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 1035d11278e3SHarman Kalra } 1036d11278e3SHarman Kalra 1037795ac238SJerin Jacob rc = roc_npc_mcam_free_all_resources(npc); 1038795ac238SJerin Jacob if (rc) { 1039d11278e3SHarman Kalra rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1040d11278e3SHarman Kalra "Failed to flush filter"); 1041795ac238SJerin Jacob return -rte_errno; 1042795ac238SJerin Jacob } 1043795ac238SJerin Jacob 1044795ac238SJerin Jacob return 0; 1045795ac238SJerin Jacob } 1046795ac238SJerin Jacob 1047795ac238SJerin Jacob static int 1048d11278e3SHarman Kalra cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error) 1049d11278e3SHarman Kalra { 1050d11278e3SHarman Kalra return cnxk_flow_flush_common(eth_dev, error, false); 1051d11278e3SHarman Kalra } 1052d11278e3SHarman Kalra 1053d11278e3SHarman Kalra int 1054d11278e3SHarman Kalra cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow, 1055795ac238SJerin Jacob const struct rte_flow_action *action, void *data, 1056d11278e3SHarman Kalra struct rte_flow_error *error, bool is_rep) 1057795ac238SJerin Jacob { 1058795ac238SJerin Jacob struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow; 1059795ac238SJerin Jacob struct rte_flow_query_count *query = data; 1060d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 1061d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 1062d11278e3SHarman Kalra struct roc_npc *npc; 1063795ac238SJerin Jacob const char *errmsg = NULL; 1064795ac238SJerin Jacob int errcode = ENOTSUP; 1065795ac238SJerin Jacob int rc; 1066795ac238SJerin Jacob 1067795ac238SJerin Jacob if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) { 1068795ac238SJerin Jacob errmsg = "Only COUNT is supported in query"; 1069795ac238SJerin Jacob goto err_exit; 1070795ac238SJerin Jacob } 1071795ac238SJerin Jacob 1072795ac238SJerin Jacob if (in_flow->ctr_id == NPC_COUNTER_NONE) { 1073795ac238SJerin Jacob errmsg = "Counter is not available"; 1074795ac238SJerin Jacob goto err_exit; 1075795ac238SJerin Jacob } 1076795ac238SJerin Jacob 1077d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 1078d11278e3SHarman Kalra if (!is_rep) { 1079d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 1080d11278e3SHarman Kalra npc = &dev->npc; 1081d11278e3SHarman Kalra } else { 1082d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 1083d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 1084d11278e3SHarman Kalra } 1085d11278e3SHarman Kalra 1086df5cf15fSKiran Kumar K if (in_flow->use_pre_alloc) 1087df5cf15fSKiran Kumar K rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits); 1088df5cf15fSKiran Kumar K else 1089795ac238SJerin Jacob rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits); 1090795ac238SJerin Jacob if (rc != 0) { 1091795ac238SJerin Jacob errcode = EIO; 1092795ac238SJerin Jacob errmsg = "Error reading flow counter"; 1093795ac238SJerin Jacob goto err_exit; 1094795ac238SJerin Jacob } 1095795ac238SJerin Jacob query->hits_set = 1; 1096795ac238SJerin Jacob query->bytes_set = 0; 1097795ac238SJerin Jacob 1098df5cf15fSKiran Kumar K if (query->reset) { 1099df5cf15fSKiran Kumar K if (in_flow->use_pre_alloc) 1100df5cf15fSKiran Kumar K rc = roc_npc_inl_mcam_clear_counter(in_flow->ctr_id); 1101df5cf15fSKiran Kumar K else 1102795ac238SJerin Jacob rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id); 1103df5cf15fSKiran Kumar K } 1104795ac238SJerin Jacob if (rc != 0) { 1105795ac238SJerin Jacob errcode = EIO; 1106795ac238SJerin Jacob errmsg = "Error clearing flow counter"; 1107795ac238SJerin Jacob goto err_exit; 1108795ac238SJerin Jacob } 1109795ac238SJerin Jacob 1110795ac238SJerin Jacob return 0; 1111795ac238SJerin Jacob 1112795ac238SJerin Jacob err_exit: 1113795ac238SJerin Jacob rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 1114795ac238SJerin Jacob NULL, errmsg); 1115795ac238SJerin Jacob return -rte_errno; 1116795ac238SJerin Jacob } 1117795ac238SJerin Jacob 1118795ac238SJerin Jacob static int 1119d11278e3SHarman Kalra cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow, 1120d11278e3SHarman Kalra const struct rte_flow_action *action, void *data, struct rte_flow_error *error) 1121d11278e3SHarman Kalra { 1122d11278e3SHarman Kalra return cnxk_flow_query_common(eth_dev, flow, action, data, error, false); 1123d11278e3SHarman Kalra } 1124d11278e3SHarman Kalra 1125d11278e3SHarman Kalra static int 1126d11278e3SHarman Kalra cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused, int enable __rte_unused, 1127d11278e3SHarman Kalra struct rte_flow_error *error) 1128795ac238SJerin Jacob { 1129795ac238SJerin Jacob /* If we support, we need to un-install the default mcam 1130795ac238SJerin Jacob * entry for this port. 1131795ac238SJerin Jacob */ 1132795ac238SJerin Jacob 1133795ac238SJerin Jacob rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 1134795ac238SJerin Jacob NULL, "Flow isolation not supported"); 1135795ac238SJerin Jacob 1136795ac238SJerin Jacob return -rte_errno; 1137795ac238SJerin Jacob } 1138795ac238SJerin Jacob 1139d11278e3SHarman Kalra int 1140d11278e3SHarman Kalra cnxk_flow_dev_dump_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file, 1141d11278e3SHarman Kalra struct rte_flow_error *error, bool is_rep) 1142795ac238SJerin Jacob { 1143d11278e3SHarman Kalra struct cnxk_rep_dev *rep_dev; 1144d11278e3SHarman Kalra struct cnxk_eth_dev *dev; 1145d11278e3SHarman Kalra struct roc_npc *npc; 1146d11278e3SHarman Kalra 1147d11278e3SHarman Kalra /* is_rep set for operation performed via representor ports */ 1148d11278e3SHarman Kalra if (!is_rep) { 1149d11278e3SHarman Kalra dev = cnxk_eth_pmd_priv(eth_dev); 1150d11278e3SHarman Kalra npc = &dev->npc; 1151d11278e3SHarman Kalra } else { 1152d11278e3SHarman Kalra rep_dev = cnxk_rep_pmd_priv(eth_dev); 1153d11278e3SHarman Kalra npc = &rep_dev->parent_dev->npc; 1154d11278e3SHarman Kalra } 1155795ac238SJerin Jacob 1156795ac238SJerin Jacob if (file == NULL) { 1157d11278e3SHarman Kalra rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, 1158795ac238SJerin Jacob "Invalid file"); 1159795ac238SJerin Jacob return -rte_errno; 1160795ac238SJerin Jacob } 1161795ac238SJerin Jacob 1162795ac238SJerin Jacob if (flow != NULL) { 1163abdd7a9dSHarman Kalra roc_npc_flow_mcam_dump(file, npc, (struct roc_npc_flow *)flow); 1164abdd7a9dSHarman Kalra return 0; 1165795ac238SJerin Jacob } 1166795ac238SJerin Jacob 1167296e9040SKiran Kumar K roc_npc_flow_dump(file, npc, -1); 1168795ac238SJerin Jacob 1169795ac238SJerin Jacob return 0; 1170795ac238SJerin Jacob } 1171795ac238SJerin Jacob 1172a4477550SAnkur Dwivedi static int 1173d11278e3SHarman Kalra cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file, 1174d11278e3SHarman Kalra struct rte_flow_error *error) 1175d11278e3SHarman Kalra { 1176d11278e3SHarman Kalra return cnxk_flow_dev_dump_common(eth_dev, flow, file, error, false); 1177d11278e3SHarman Kalra } 1178d11278e3SHarman Kalra 1179d11278e3SHarman Kalra static int 1180d11278e3SHarman Kalra cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context, uint32_t nb_contexts, 1181d11278e3SHarman Kalra struct rte_flow_error *err) 1182a4477550SAnkur Dwivedi { 1183a4477550SAnkur Dwivedi struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); 1184a4477550SAnkur Dwivedi struct roc_npc *roc_npc = &dev->npc; 1185a4477550SAnkur Dwivedi struct roc_npc_flow_age *flow_age; 1186a4477550SAnkur Dwivedi uint32_t start_id; 1187a4477550SAnkur Dwivedi uint32_t end_id; 1188a4477550SAnkur Dwivedi int cnt = 0; 1189a4477550SAnkur Dwivedi uint32_t sn; 1190a4477550SAnkur Dwivedi uint32_t i; 1191a4477550SAnkur Dwivedi 1192a4477550SAnkur Dwivedi RTE_SET_USED(err); 1193a4477550SAnkur Dwivedi 1194a4477550SAnkur Dwivedi flow_age = &roc_npc->flow_age; 1195a4477550SAnkur Dwivedi 11964ebef525SSatheesh Paul if (!flow_age->age_flow_refcnt) 11974ebef525SSatheesh Paul return 0; 11984ebef525SSatheesh Paul 1199a4477550SAnkur Dwivedi do { 1200a4477550SAnkur Dwivedi sn = plt_seqcount_read_begin(&flow_age->seq_cnt); 1201a4477550SAnkur Dwivedi 1202a4477550SAnkur Dwivedi if (nb_contexts == 0) { 1203a4477550SAnkur Dwivedi cnt = flow_age->aged_flows_cnt; 1204a4477550SAnkur Dwivedi } else { 1205a4477550SAnkur Dwivedi start_id = flow_age->start_id; 1206a4477550SAnkur Dwivedi end_id = flow_age->end_id; 1207a4477550SAnkur Dwivedi for (i = start_id; i <= end_id; i++) { 1208a4477550SAnkur Dwivedi if ((int)nb_contexts == cnt) 1209a4477550SAnkur Dwivedi break; 1210a4477550SAnkur Dwivedi if (plt_bitmap_get(flow_age->aged_flows, i)) { 1211a4477550SAnkur Dwivedi context[cnt] = 1212a4477550SAnkur Dwivedi roc_npc_aged_flow_ctx_get(roc_npc, i); 1213a4477550SAnkur Dwivedi cnt++; 1214a4477550SAnkur Dwivedi } 1215a4477550SAnkur Dwivedi } 1216a4477550SAnkur Dwivedi } 1217a4477550SAnkur Dwivedi } while (plt_seqcount_read_retry(&flow_age->seq_cnt, sn)); 1218a4477550SAnkur Dwivedi 1219a4477550SAnkur Dwivedi return cnt; 1220a4477550SAnkur Dwivedi } 1221a4477550SAnkur Dwivedi 1222c1ae225eSHarman Kalra static int 1223c1ae225eSHarman Kalra cnxk_flow_tunnel_decap_set(__rte_unused struct rte_eth_dev *dev, struct rte_flow_tunnel *tunnel, 1224c1ae225eSHarman Kalra struct rte_flow_action **pmd_actions, uint32_t *num_of_actions, 1225c1ae225eSHarman Kalra __rte_unused struct rte_flow_error *err) 1226c1ae225eSHarman Kalra { 1227c1ae225eSHarman Kalra struct rte_flow_action *nfp_action; 1228c1ae225eSHarman Kalra 1229c1ae225eSHarman Kalra nfp_action = rte_zmalloc("nfp_tun_action", sizeof(struct rte_flow_action), 0); 1230c1ae225eSHarman Kalra if (nfp_action == NULL) { 1231c1ae225eSHarman Kalra plt_err("Alloc memory for nfp tunnel action failed."); 1232c1ae225eSHarman Kalra return -ENOMEM; 1233c1ae225eSHarman Kalra } 1234c1ae225eSHarman Kalra 1235c1ae225eSHarman Kalra if (tunnel->is_ipv6) 1236c1ae225eSHarman Kalra nfp_action->conf = (void *)~0; 1237c1ae225eSHarman Kalra 1238c1ae225eSHarman Kalra switch (tunnel->type) { 1239c1ae225eSHarman Kalra case RTE_FLOW_ITEM_TYPE_VXLAN: 1240c1ae225eSHarman Kalra nfp_action->type = RTE_FLOW_ACTION_TYPE_VXLAN_DECAP; 1241c1ae225eSHarman Kalra *pmd_actions = nfp_action; 1242c1ae225eSHarman Kalra *num_of_actions = 1; 1243c1ae225eSHarman Kalra break; 1244c1ae225eSHarman Kalra default: 1245c1ae225eSHarman Kalra *pmd_actions = NULL; 1246c1ae225eSHarman Kalra *num_of_actions = 0; 1247c1ae225eSHarman Kalra rte_free(nfp_action); 1248c1ae225eSHarman Kalra break; 1249c1ae225eSHarman Kalra } 1250c1ae225eSHarman Kalra 1251c1ae225eSHarman Kalra return 0; 1252c1ae225eSHarman Kalra } 1253c1ae225eSHarman Kalra 1254c1ae225eSHarman Kalra static int 1255c1ae225eSHarman Kalra cnxk_flow_tunnel_action_decap_release(__rte_unused struct rte_eth_dev *dev, 1256c1ae225eSHarman Kalra struct rte_flow_action *pmd_actions, uint32_t num_of_actions, 1257c1ae225eSHarman Kalra __rte_unused struct rte_flow_error *err) 1258c1ae225eSHarman Kalra { 1259c1ae225eSHarman Kalra uint32_t i; 1260c1ae225eSHarman Kalra struct rte_flow_action *nfp_action; 1261c1ae225eSHarman Kalra 1262c1ae225eSHarman Kalra for (i = 0; i < num_of_actions; i++) { 1263c1ae225eSHarman Kalra nfp_action = &pmd_actions[i]; 1264c1ae225eSHarman Kalra nfp_action->conf = NULL; 1265c1ae225eSHarman Kalra rte_free(nfp_action); 1266c1ae225eSHarman Kalra } 1267c1ae225eSHarman Kalra 1268c1ae225eSHarman Kalra return 0; 1269c1ae225eSHarman Kalra } 1270c1ae225eSHarman Kalra 1271c1ae225eSHarman Kalra static int 1272c1ae225eSHarman Kalra cnxk_flow_tunnel_match(__rte_unused struct rte_eth_dev *dev, 1273c1ae225eSHarman Kalra __rte_unused struct rte_flow_tunnel *tunnel, 1274c1ae225eSHarman Kalra __rte_unused struct rte_flow_item **pmd_items, uint32_t *num_of_items, 1275c1ae225eSHarman Kalra __rte_unused struct rte_flow_error *err) 1276c1ae225eSHarman Kalra { 1277c1ae225eSHarman Kalra *num_of_items = 0; 1278c1ae225eSHarman Kalra 1279c1ae225eSHarman Kalra return 0; 1280c1ae225eSHarman Kalra } 1281c1ae225eSHarman Kalra 1282c1ae225eSHarman Kalra static int 1283c1ae225eSHarman Kalra cnxk_flow_tunnel_item_release(__rte_unused struct rte_eth_dev *dev, 1284c1ae225eSHarman Kalra __rte_unused struct rte_flow_item *pmd_items, 1285c1ae225eSHarman Kalra __rte_unused uint32_t num_of_items, 1286c1ae225eSHarman Kalra __rte_unused struct rte_flow_error *err) 1287c1ae225eSHarman Kalra { 1288c1ae225eSHarman Kalra return 0; 1289c1ae225eSHarman Kalra } 1290c1ae225eSHarman Kalra 1291795ac238SJerin Jacob struct rte_flow_ops cnxk_flow_ops = { 1292795ac238SJerin Jacob .validate = cnxk_flow_validate, 1293795ac238SJerin Jacob .flush = cnxk_flow_flush, 1294795ac238SJerin Jacob .query = cnxk_flow_query, 1295795ac238SJerin Jacob .isolate = cnxk_flow_isolate, 1296795ac238SJerin Jacob .dev_dump = cnxk_flow_dev_dump, 1297a4477550SAnkur Dwivedi .get_aged_flows = cnxk_flow_get_aged_flows, 1298c1ae225eSHarman Kalra .tunnel_match = cnxk_flow_tunnel_match, 1299c1ae225eSHarman Kalra .tunnel_item_release = cnxk_flow_tunnel_item_release, 1300c1ae225eSHarman Kalra .tunnel_decap_set = cnxk_flow_tunnel_decap_set, 1301c1ae225eSHarman Kalra .tunnel_action_decap_release = cnxk_flow_tunnel_action_decap_release, 1302795ac238SJerin Jacob }; 1303