LCOV - code coverage report
Current view: top level - drivers/net/cnxk - cnxk_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 1176 0.0 %
Date: 2026-10-01 18:19:24 Functions: 0 44 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 679 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : #include <cnxk_flow.h>
       5                 :            : #include <cnxk_rep.h>
       6                 :            : 
       7                 :            : #define IS_REP_BIT 7
       8                 :            : 
       9                 :            : #define TNL_DCP_MATCH_ID 5
      10                 :            : #define NRML_MATCH_ID    1
      11                 :            : 
      12                 :            : const struct cnxk_rte_flow_term_info term[] = {
      13                 :            :         [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH, sizeof(struct rte_flow_item_eth)},
      14                 :            :         [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN, sizeof(struct rte_flow_item_vlan)},
      15                 :            :         [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG, sizeof(struct rte_flow_item_e_tag)},
      16                 :            :         [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4, sizeof(struct rte_flow_item_ipv4)},
      17                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6, sizeof(struct rte_flow_item_ipv6)},
      18                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT,
      19                 :            :                                               sizeof(struct rte_flow_item_ipv6_frag_ext)},
      20                 :            :         [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
      21                 :            :                                              sizeof(struct rte_flow_item_arp_eth_ipv4)},
      22                 :            :         [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS, sizeof(struct rte_flow_item_mpls)},
      23                 :            :         [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP, sizeof(struct rte_flow_item_icmp)},
      24                 :            :         [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP, sizeof(struct rte_flow_item_udp)},
      25                 :            :         [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP, sizeof(struct rte_flow_item_tcp)},
      26                 :            :         [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP, sizeof(struct rte_flow_item_sctp)},
      27                 :            :         [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP, sizeof(struct rte_flow_item_esp)},
      28                 :            :         [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE, sizeof(struct rte_flow_item_gre)},
      29                 :            :         [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE, sizeof(struct rte_flow_item_nvgre)},
      30                 :            :         [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN, sizeof(struct rte_flow_item_vxlan)},
      31                 :            :         [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC, sizeof(struct rte_flow_item_gtp)},
      32                 :            :         [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU, sizeof(struct rte_flow_item_gtp)},
      33                 :            :         [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE,
      34                 :            :                                        sizeof(struct rte_flow_item_geneve)},
      35                 :            :         [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {ROC_NPC_ITEM_TYPE_VXLAN_GPE,
      36                 :            :                                           sizeof(struct rte_flow_item_vxlan_gpe)},
      37                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT,
      38                 :            :                                          sizeof(struct rte_flow_item_ipv6_ext)},
      39                 :            :         [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0},
      40                 :            :         [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
      41                 :            :         [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY, sizeof(uint32_t)},
      42                 :            :         [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2,
      43                 :            :                                        sizeof(struct rte_flow_item_higig2_hdr)},
      44                 :            :         [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW, sizeof(struct rte_flow_item_raw)},
      45                 :            :         [RTE_FLOW_ITEM_TYPE_MARK] = {ROC_NPC_ITEM_TYPE_MARK, sizeof(struct rte_flow_item_mark)},
      46                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_ROUTING_EXT,
      47                 :            :                                                  sizeof(struct rte_flow_item_ipv6_routing_ext)},
      48                 :            :         [RTE_FLOW_ITEM_TYPE_TX_QUEUE] = {ROC_NPC_ITEM_TYPE_TX_QUEUE,
      49                 :            :                                          sizeof(struct rte_flow_item_tx_queue)},
      50                 :            :         [RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT] = {ROC_NPC_ITEM_TYPE_REPRESENTED_PORT,
      51                 :            :                                                  sizeof(struct rte_flow_item_ethdev)},
      52                 :            :         [RTE_FLOW_ITEM_TYPE_PPPOES] = {ROC_NPC_ITEM_TYPE_PPPOES,
      53                 :            :                                        sizeof(struct rte_flow_item_pppoe)}};
      54                 :            : 
      55                 :            : static int
      56                 :          0 : npc_rss_action_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
      57                 :            :                         const struct rte_flow_action *act)
      58                 :            : {
      59                 :            :         const struct rte_flow_action_rss *rss;
      60                 :            : 
      61                 :          0 :         rss = (const struct rte_flow_action_rss *)act->conf;
      62                 :            : 
      63         [ #  # ]:          0 :         if (attr->egress) {
      64                 :          0 :                 plt_err("No support of RSS in egress");
      65                 :          0 :                 return -EINVAL;
      66                 :            :         }
      67                 :            : 
      68         [ #  # ]:          0 :         if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
      69                 :          0 :                 plt_err("multi-queue mode is disabled");
      70                 :          0 :                 return -ENOTSUP;
      71                 :            :         }
      72                 :            : 
      73   [ #  #  #  # ]:          0 :         if (!rss || !rss->queue_num) {
      74                 :          0 :                 plt_err("no valid queues");
      75                 :          0 :                 return -EINVAL;
      76                 :            :         }
      77                 :            : 
      78         [ #  # ]:          0 :         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
      79                 :          0 :                 plt_err("non-default RSS hash functions are not supported");
      80                 :          0 :                 return -ENOTSUP;
      81                 :            :         }
      82                 :            : 
      83         [ #  # ]:          0 :         if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
      84                 :          0 :                 plt_err("RSS hash key too large");
      85                 :          0 :                 return -ENOTSUP;
      86                 :            :         }
      87                 :            : 
      88                 :            :         return 0;
      89                 :            : }
      90                 :            : 
      91                 :            : static void
      92                 :            : npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev, const struct roc_npc_action *rss_action,
      93                 :            :                     uint32_t *flowkey_cfg, uint64_t default_rss_types)
      94                 :            : {
      95                 :            :         const struct roc_npc_action_rss *rss;
      96                 :            :         uint64_t rss_types;
      97                 :            : 
      98                 :            :         rss = (const struct roc_npc_action_rss *)rss_action->conf;
      99                 :          0 :         rss_types = rss->types;
     100                 :            :         /* If no RSS types are specified, use default one */
     101                 :          0 :         if (rss_types == 0)
     102                 :            :                 rss_types = default_rss_types;
     103                 :            : 
     104                 :          0 :         *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss_types, rss->level);
     105                 :          0 : }
     106                 :            : 
     107                 :            : static int
     108                 :          0 : npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct rte_flow_action *action,
     109                 :            :                          uint16_t *dst_pf_func, uint16_t *dst_channel)
     110                 :            : {
     111                 :            :         const struct rte_flow_action_port_id *port_act;
     112                 :            :         struct rte_eth_dev *portid_eth_dev;
     113                 :            :         char if_name[RTE_ETH_NAME_MAX_LEN];
     114                 :            :         struct cnxk_eth_dev *hw_dst;
     115                 :            :         struct roc_npc *roc_npc_dst;
     116                 :            :         int rc = 0;
     117                 :            : 
     118                 :          0 :         port_act = (const struct rte_flow_action_port_id *)action->conf;
     119                 :            : 
     120                 :          0 :         rc = rte_eth_dev_get_name_by_port(port_act->id, if_name);
     121         [ #  # ]:          0 :         if (rc) {
     122                 :          0 :                 plt_err("Name not found for output port id");
     123                 :          0 :                 goto err_exit;
     124                 :            :         }
     125                 :          0 :         portid_eth_dev = rte_eth_dev_allocated(if_name);
     126         [ #  # ]:          0 :         if (!portid_eth_dev) {
     127                 :          0 :                 plt_err("eth_dev not found for output port id");
     128                 :          0 :                 goto err_exit;
     129                 :            :         }
     130         [ #  # ]:          0 :         if (strcmp(portid_eth_dev->device->driver->name, eth_dev->device->driver->name) != 0) {
     131                 :          0 :                 plt_err("Output port not under same driver");
     132                 :          0 :                 goto err_exit;
     133                 :            :         }
     134                 :          0 :         hw_dst = portid_eth_dev->data->dev_private;
     135                 :            :         roc_npc_dst = &hw_dst->npc;
     136                 :          0 :         *dst_pf_func = roc_npc_dst->pf_func;
     137                 :          0 :         *dst_channel = hw_dst->npc.channel;
     138                 :            : 
     139                 :          0 :         return 0;
     140                 :            : 
     141                 :            : err_exit:
     142                 :            :         return -EINVAL;
     143                 :            : }
     144                 :            : 
     145                 :            : static int
     146                 :          0 : roc_npc_parse_sample_subaction(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[],
     147                 :            :                                struct roc_npc_action_sample *sample_action)
     148                 :            : {
     149                 :          0 :         uint16_t dst_pf_func = 0, dst_channel = 0;
     150                 :            :         const struct roc_npc_action_vf *vf_act;
     151                 :            :         int rc = 0, count = 0;
     152                 :            :         bool is_empty = true;
     153                 :            : 
     154         [ #  # ]:          0 :         if (sample_action->ratio != 1) {
     155                 :          0 :                 plt_err("Sample ratio must be 1");
     156                 :          0 :                 return -EINVAL;
     157                 :            :         }
     158                 :            : 
     159         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     160                 :            :                 is_empty = false;
     161   [ #  #  #  # ]:          0 :                 switch (actions->type) {
     162                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PF:
     163                 :          0 :                         count++;
     164                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_PF;
     165                 :          0 :                         break;
     166                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VF:
     167                 :          0 :                         count++;
     168                 :          0 :                         vf_act = (const struct roc_npc_action_vf *)actions->conf;
     169                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_VF;
     170                 :          0 :                         sample_action->pf_func = vf_act->id & NPC_PFVF_FUNC_MASK;
     171                 :          0 :                         break;
     172                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
     173                 :          0 :                         rc = npc_parse_port_id_action(eth_dev, actions, &dst_pf_func, &dst_channel);
     174         [ #  # ]:          0 :                         if (rc)
     175                 :            :                                 return -EINVAL;
     176                 :            : 
     177                 :          0 :                         count++;
     178                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_PORT_ID;
     179                 :          0 :                         sample_action->pf_func = dst_pf_func;
     180                 :          0 :                         sample_action->channel = dst_channel;
     181                 :          0 :                         break;
     182                 :          0 :                 default:
     183                 :          0 :                         continue;
     184                 :            :                 }
     185                 :            :         }
     186                 :            : 
     187         [ #  # ]:          0 :         if (count > 1 || is_empty)
     188                 :          0 :                 return -EINVAL;
     189                 :            : 
     190                 :            :         return 0;
     191                 :            : }
     192                 :            : 
     193                 :            : static int
     194                 :          0 : append_mark_action(struct roc_npc_action *in_actions, uint8_t has_tunnel_pattern,
     195                 :            :                    uint64_t *free_allocs, int *act_cnt)
     196                 :            : {
     197                 :            :         struct rte_flow_action_mark *act_mark;
     198                 :          0 :         int i = *act_cnt, j = 0;
     199                 :            : 
     200                 :            :         /* Add Mark action */
     201                 :          0 :         i++;
     202                 :          0 :         act_mark = plt_zmalloc(sizeof(struct rte_flow_action_mark), 0);
     203         [ #  # ]:          0 :         if (!act_mark) {
     204                 :          0 :                 plt_err("Error allocation memory");
     205                 :          0 :                 return -ENOMEM;
     206                 :            :         }
     207                 :            : 
     208         [ #  # ]:          0 :         while (free_allocs[j] != 0)
     209                 :          0 :                 j++;
     210                 :          0 :         free_allocs[j] = (uint64_t)act_mark;
     211                 :            :         /* Mark ID format: (tunnel type - VxLAN, Geneve << 6) | Tunnel decap */
     212                 :          0 :         act_mark->id =
     213         [ #  # ]:          0 :                 has_tunnel_pattern ? ((has_tunnel_pattern << 6) | TNL_DCP_MATCH_ID) : NRML_MATCH_ID;
     214                 :          0 :         in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
     215                 :          0 :         in_actions[i].conf = (struct rte_flow_action_mark *)act_mark;
     216                 :            : 
     217                 :          0 :         plt_rep_dbg("Assigned mark ID %x", act_mark->id);
     218                 :            : 
     219                 :          0 :         *act_cnt = i;
     220                 :            : 
     221                 :          0 :         return 0;
     222                 :            : }
     223                 :            : 
     224                 :            : static int
     225                 :          0 : append_rss_action(struct cnxk_eth_dev *dev, struct roc_npc_action *in_actions, uint16_t nb_rxq,
     226                 :            :                   uint32_t *flowkey_cfg, uint64_t *free_allocs, uint16_t rss_repte_pf_func,
     227                 :            :                   int *act_cnt)
     228                 :            : {
     229                 :            :         struct roc_npc_action_rss *rss_conf;
     230                 :          0 :         int i = *act_cnt, j = 0, l, rc = 0;
     231                 :            :         uint16_t *queue_arr;
     232                 :            : 
     233                 :          0 :         rss_conf = plt_zmalloc(sizeof(struct roc_npc_action_rss), 0);
     234         [ #  # ]:          0 :         if (!rss_conf) {
     235                 :          0 :                 plt_err("Failed to allocate memory for rss conf");
     236                 :            :                 rc = -ENOMEM;
     237                 :          0 :                 goto fail;
     238                 :            :         }
     239                 :            : 
     240                 :            :         /* Add RSS action */
     241                 :          0 :         rss_conf->queue_num = nb_rxq;
     242                 :          0 :         queue_arr = plt_zmalloc(rss_conf->queue_num * sizeof(uint16_t), 0);
     243         [ #  # ]:          0 :         if (!queue_arr) {
     244                 :          0 :                 plt_err("Failed to allocate memory for rss queue");
     245                 :            :                 rc = -ENOMEM;
     246                 :          0 :                 goto free_rss;
     247                 :            :         }
     248                 :            : 
     249         [ #  # ]:          0 :         for (l = 0; l < nb_rxq; l++)
     250                 :          0 :                 queue_arr[l] = l;
     251                 :          0 :         rss_conf->queue = queue_arr;
     252                 :          0 :         rss_conf->key = NULL;
     253                 :          0 :         rss_conf->types = RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP;
     254                 :            : 
     255                 :          0 :         i++;
     256                 :            : 
     257                 :          0 :         in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
     258                 :          0 :         in_actions[i].conf = (struct roc_npc_action_rss *)rss_conf;
     259                 :          0 :         in_actions[i].rss_repte_pf_func = rss_repte_pf_func;
     260                 :            : 
     261                 :            :         npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg,
     262                 :            :                             RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP);
     263                 :            : 
     264                 :          0 :         *act_cnt = i;
     265                 :            : 
     266         [ #  # ]:          0 :         while (free_allocs[j] != 0)
     267                 :          0 :                 j++;
     268                 :          0 :         free_allocs[j] = (uint64_t)rss_conf;
     269                 :          0 :         j++;
     270                 :          0 :         free_allocs[j] = (uint64_t)queue_arr;
     271                 :            : 
     272                 :          0 :         return 0;
     273                 :            : free_rss:
     274                 :          0 :         plt_free(rss_conf);
     275                 :            : fail:
     276                 :            :         return rc;
     277                 :            : }
     278                 :            : 
     279                 :            : static int
     280         [ #  # ]:          0 : representor_rep_portid_action(struct roc_npc_action *in_actions, struct rte_eth_dev *eth_dev,
     281                 :            :                               struct rte_eth_dev *portid_eth_dev,
     282                 :            :                               enum rte_flow_action_type act_type, uint8_t rep_pattern,
     283                 :            :                               uint16_t *dst_pf_func, bool is_rep, uint8_t has_tunnel_pattern,
     284                 :            :                               uint64_t *free_allocs, int *act_cnt, uint32_t *flowkey_cfg)
     285                 :            : {
     286                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     287                 :            :         struct rte_eth_dev *rep_eth_dev = portid_eth_dev;
     288                 :            :         struct rte_flow_action_of_set_vlan_vid *vlan_vid;
     289                 :            :         struct rte_flow_action_of_set_vlan_pcp *vlan_pcp;
     290                 :            :         struct rte_flow_action_of_push_vlan *push_vlan;
     291                 :            :         struct rte_flow_action_queue *act_q = NULL;
     292                 :            :         struct cnxk_rep_dev *rep_dev;
     293                 :            :         struct roc_npc *npc;
     294                 :            :         uint16_t vlan_tci;
     295                 :            :         int j = 0, rc;
     296                 :            : 
     297                 :            :         /* For inserting an action in the list */
     298         [ #  # ]:          0 :         int i = *act_cnt;
     299                 :            : 
     300                 :            :         rep_dev = cnxk_rep_pmd_priv(rep_eth_dev);
     301         [ #  # ]:          0 :         if (!is_rep) {
     302                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
     303                 :          0 :                 npc = &dev->npc;
     304                 :            :         } else {
     305                 :          0 :                 npc = &rep_dev->parent_dev->npc;
     306                 :            :         }
     307         [ #  # ]:          0 :         if (rep_pattern >> IS_REP_BIT) { /* Check for normal/representor port as action */
     308         [ #  # ]:          0 :                 if ((rep_pattern & 0x7f) == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) {
     309                 :            :                         /* Case: Repr port pattern -> Default TX rule -> LBK ->
     310                 :            :                          *  Pattern RX LBK rule hit -> Action: send to new pf_func
     311                 :            :                          */
     312         [ #  # ]:          0 :                         if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) {
     313                 :            :                                 /* New pf_func corresponds to ESW + queue corresponding to rep_id */
     314                 :          0 :                                 act_q = plt_zmalloc(sizeof(struct rte_flow_action_queue), 0);
     315         [ #  # ]:          0 :                                 if (!act_q) {
     316                 :          0 :                                         plt_err("Error allocation memory");
     317                 :          0 :                                         return -ENOMEM;
     318                 :            :                                 }
     319                 :          0 :                                 act_q->index = rep_dev->rep_id;
     320                 :            : 
     321         [ #  # ]:          0 :                                 while (free_allocs[j] != 0)
     322                 :          0 :                                         j++;
     323                 :          0 :                                 free_allocs[j] = (uint64_t)act_q;
     324                 :          0 :                                 in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
     325                 :          0 :                                 in_actions[i].conf = (struct rte_flow_action_queue *)act_q;
     326                 :          0 :                                 npc->rep_act_pf_func = rep_dev->parent_dev->npc.pf_func;
     327                 :            :                         } else {
     328                 :            :                                 /* New pf_func corresponds to hw_func of representee */
     329                 :          0 :                                 in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
     330                 :          0 :                                 npc->rep_act_pf_func = rep_dev->hw_func;
     331                 :          0 :                                 *dst_pf_func = rep_dev->hw_func;
     332                 :            :                         }
     333                 :            :                         /* Additional action to strip the VLAN from packets received by LBK */
     334                 :          0 :                         i++;
     335                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
     336                 :          0 :                         goto done;
     337                 :            :                 }
     338                 :            :                 /* Case: Repd port pattern -> TX Rule with VLAN -> LBK -> Default RX LBK rule hit
     339                 :            :                  * base on vlan, if packet goes to ESW or actual pf_func -> Action :
     340                 :            :                  *    act port_representor: send to ESW respective using 1<<8 | rep_id as tci value
     341                 :            :                  *    act represented_port: send to actual port using rep_id as tci value.
     342                 :            :                  */
     343                 :            :                 /* Add RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN action */
     344                 :          0 :                 push_vlan = plt_zmalloc(sizeof(struct rte_flow_action_of_push_vlan), 0);
     345         [ #  # ]:          0 :                 if (!push_vlan) {
     346                 :          0 :                         plt_err("Error allocation memory");
     347                 :          0 :                         return -ENOMEM;
     348                 :            :                 }
     349                 :            : 
     350         [ #  # ]:          0 :                 while (free_allocs[j] != 0)
     351                 :          0 :                         j++;
     352                 :          0 :                 free_allocs[j] = (uint64_t)push_vlan;
     353                 :          0 :                 push_vlan->ethertype = ntohs(ROC_ESWITCH_VLAN_TPID);
     354                 :          0 :                 in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
     355                 :          0 :                 in_actions[i].conf = (struct rte_flow_action_of_push_vlan *)push_vlan;
     356                 :          0 :                 i++;
     357                 :            : 
     358                 :            :                 /* Add RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP action */
     359                 :          0 :                 vlan_pcp = plt_zmalloc(sizeof(struct rte_flow_action_of_set_vlan_pcp), 0);
     360         [ #  # ]:          0 :                 if (!vlan_pcp) {
     361                 :          0 :                         plt_err("Error allocation memory");
     362                 :          0 :                         return -ENOMEM;
     363                 :            :                 }
     364                 :            : 
     365                 :          0 :                 free_allocs[j + 1] = (uint64_t)vlan_pcp;
     366                 :          0 :                 vlan_pcp->vlan_pcp = 0;
     367                 :          0 :                 in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
     368                 :          0 :                 in_actions[i].conf = (struct rte_flow_action_of_set_vlan_pcp *)vlan_pcp;
     369                 :          0 :                 i++;
     370                 :            : 
     371                 :            :                 /* Add RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID action */
     372                 :          0 :                 vlan_vid = plt_zmalloc(sizeof(struct rte_flow_action_of_set_vlan_vid), 0);
     373         [ #  # ]:          0 :                 if (!vlan_vid) {
     374                 :          0 :                         plt_err("Error allocation memory");
     375                 :          0 :                         return -ENOMEM;
     376                 :            :                 }
     377                 :            : 
     378                 :          0 :                 free_allocs[j + 2] = (uint64_t)vlan_vid;
     379         [ #  # ]:          0 :                 if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR)
     380                 :          0 :                         vlan_tci = rep_dev->rep_id | (1ULL << CNXK_ESWITCH_VFPF_SHIFT);
     381                 :            :                 else
     382                 :          0 :                         vlan_tci = rep_dev->rep_id;
     383                 :          0 :                 vlan_vid->vlan_vid = ntohs(vlan_tci);
     384                 :          0 :                 in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
     385                 :          0 :                 in_actions[i].conf = (struct rte_flow_action_of_set_vlan_vid *)vlan_vid;
     386                 :            : 
     387                 :            :                 /* Change default channel to UCAST_CHAN (63) while sending */
     388                 :          0 :                 npc->rep_act_rep = true;
     389                 :            :         } else {
     390         [ #  # ]:          0 :                 if (act_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) {
     391                 :            :                         /* Case: Pattern wire port ->  Pattern RX rule->
     392                 :            :                          * Action: pf_func = ESW. queue = rep_id
     393                 :            :                          */
     394                 :          0 :                         act_q = plt_zmalloc(sizeof(struct rte_flow_action_queue), 0);
     395         [ #  # ]:          0 :                         if (!act_q) {
     396                 :          0 :                                 plt_err("Error allocation memory");
     397                 :          0 :                                 return -ENOMEM;
     398                 :            :                         }
     399         [ #  # ]:          0 :                         while (free_allocs[j] != 0)
     400                 :          0 :                                 j++;
     401                 :          0 :                         free_allocs[j] = (uint64_t)act_q;
     402                 :          0 :                         act_q->index = rep_dev->rep_id;
     403                 :            : 
     404                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
     405                 :          0 :                         in_actions[i].conf = (struct rte_flow_action_queue *)act_q;
     406                 :          0 :                         npc->rep_act_pf_func = rep_dev->parent_dev->npc.pf_func;
     407                 :            :                 } else {
     408                 :            :                         /* Case: Pattern wire port -> Pattern RX rule->
     409                 :            :                          * Action: Receive at actual hw_func
     410                 :            :                          */
     411                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
     412                 :          0 :                         npc->rep_act_pf_func = rep_dev->hw_func;
     413                 :          0 :                         *dst_pf_func = rep_dev->hw_func;
     414                 :            : 
     415                 :            :                         /* Append a mark action - needed to identify the flow */
     416                 :          0 :                         rc = append_mark_action(in_actions, has_tunnel_pattern, free_allocs, &i);
     417         [ #  # ]:          0 :                         if (rc)
     418                 :            :                                 return rc;
     419                 :            :                         /* Append RSS action if representee has RSS enabled */
     420         [ #  # ]:          0 :                         if (rep_dev->nb_rxq > 1) {
     421                 :            :                                 /* PF can install rule for only its VF acting as representee */
     422   [ #  #  #  # ]:          0 :                                 if (rep_dev->hw_func &&
     423                 :          0 :                                     roc_eswitch_is_repte_pfs_vf(rep_dev->hw_func,
     424                 :          0 :                                                         roc_nix_get_pf_func(npc->roc_nix))) {
     425                 :          0 :                                         rc = append_rss_action(dev, in_actions, rep_dev->nb_rxq,
     426                 :            :                                                                flowkey_cfg, free_allocs,
     427                 :          0 :                                                                rep_dev->hw_func, &i);
     428         [ #  # ]:          0 :                                         if (rc)
     429                 :            :                                                 return rc;
     430                 :            :                                 }
     431                 :            :                         }
     432                 :            :                 }
     433                 :            :         }
     434                 :          0 : done:
     435                 :          0 :         *act_cnt = i;
     436                 :            : 
     437                 :          0 :         return 0;
     438                 :            : }
     439                 :            : 
     440                 :            : static int
     441                 :          0 : representor_portid_action(struct roc_npc_action *in_actions, struct rte_eth_dev *portid_eth_dev,
     442                 :            :                           uint16_t *dst_pf_func, uint8_t has_tunnel_pattern, uint64_t *free_allocs,
     443                 :            :                           int *act_cnt)
     444                 :            : {
     445                 :            :         struct rte_eth_dev *rep_eth_dev = portid_eth_dev;
     446                 :            :         struct cnxk_rep_dev *rep_dev;
     447                 :            :         /* For inserting an action in the list */
     448                 :          0 :         int i = *act_cnt, rc;
     449                 :            : 
     450                 :            :         rep_dev = cnxk_rep_pmd_priv(rep_eth_dev);
     451                 :            : 
     452                 :          0 :         *dst_pf_func = rep_dev->hw_func;
     453                 :            : 
     454                 :          0 :         rc = append_mark_action(in_actions, has_tunnel_pattern, free_allocs, &i);
     455         [ #  # ]:          0 :         if (rc)
     456                 :            :                 return rc;
     457                 :            : 
     458                 :          0 :         *act_cnt = i;
     459                 :          0 :         plt_rep_dbg("Rep port %d ID %d rep_dev->hw_func 0x%x", rep_dev->port_id, rep_dev->rep_id,
     460                 :            :                     rep_dev->hw_func);
     461                 :            : 
     462                 :          0 :         return 0;
     463                 :            : }
     464                 :            : 
     465                 :            : static int
     466                 :          0 : cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     467                 :            :                  const struct rte_flow_action actions[], struct roc_npc_action in_actions[],
     468                 :            :                  struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
     469                 :            :                  uint16_t *dst_pf_func, uint64_t *npc_default_action, uint8_t has_tunnel_pattern,
     470                 :            :                  bool is_rep, uint8_t rep_pattern, uint64_t *free_allocs, uint32_t flow_flags)
     471                 :            : {
     472                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     473                 :            :         const struct rte_flow_action_queue *act_q = NULL;
     474                 :            :         const struct rte_flow_action_ethdev *act_ethdev;
     475                 :            :         const struct rte_flow_action_sample *act_sample;
     476                 :            :         const struct rte_flow_action_port_id *port_act;
     477                 :            :         struct rte_eth_dev *portid_eth_dev;
     478                 :            :         char if_name[RTE_ETH_NAME_MAX_LEN];
     479                 :            :         struct cnxk_eth_dev *hw_dst;
     480                 :            :         struct roc_npc *roc_npc_dst;
     481                 :            :         bool is_vf_action = false;
     482                 :          0 :         int i = 0, rc = 0;
     483                 :            :         int rq;
     484                 :            : 
     485         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     486   [ #  #  #  #  :          0 :                 switch (actions->type) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     487                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VOID:
     488                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
     489                 :          0 :                         break;
     490                 :            : 
     491                 :          0 :                 case RTE_FLOW_ACTION_TYPE_MARK:
     492                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
     493                 :          0 :                         in_actions[i].conf = actions->conf;
     494                 :          0 :                         break;
     495                 :            : 
     496                 :          0 :                 case RTE_FLOW_ACTION_TYPE_FLAG:
     497                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
     498                 :          0 :                         break;
     499                 :            : 
     500                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
     501                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
     502                 :          0 :                         break;
     503                 :            : 
     504                 :          0 :                 case RTE_FLOW_ACTION_TYPE_DROP:
     505                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
     506                 :          0 :                         break;
     507                 :            : 
     508                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PF:
     509                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
     510                 :          0 :                         break;
     511                 :            : 
     512                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VF:
     513                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
     514                 :          0 :                         in_actions[i].conf = actions->conf;
     515                 :            :                         is_vf_action = true;
     516                 :          0 :                         break;
     517                 :            : 
     518                 :          0 :                 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
     519                 :            :                 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
     520                 :          0 :                         in_actions[i].conf = actions->conf;
     521                 :            :                         act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf;
     522         [ #  # ]:          0 :                         if (rte_eth_dev_get_name_by_port(act_ethdev->port_id, if_name)) {
     523                 :          0 :                                 plt_err("Name not found for output port id");
     524                 :          0 :                                 goto err_exit;
     525                 :            :                         }
     526                 :          0 :                         portid_eth_dev = rte_eth_dev_allocated(if_name);
     527         [ #  # ]:          0 :                         if (!portid_eth_dev) {
     528                 :          0 :                                 plt_err("eth_dev not found for output port id");
     529                 :          0 :                                 goto err_exit;
     530                 :            :                         }
     531                 :            : 
     532                 :          0 :                         plt_rep_dbg("Rule installed by port %d if_name %s act_ethdev->port_id %d",
     533                 :            :                                     eth_dev->data->port_id, if_name, act_ethdev->port_id);
     534         [ #  # ]:          0 :                         if (cnxk_ethdev_is_representor(if_name)) {
     535         [ #  # ]:          0 :                                 if (representor_rep_portid_action(in_actions, eth_dev,
     536                 :          0 :                                                                   portid_eth_dev, actions->type,
     537                 :            :                                                                   rep_pattern, dst_pf_func,
     538                 :            :                                                                   is_rep, has_tunnel_pattern,
     539                 :            :                                                                   free_allocs, &i, flowkey_cfg)) {
     540                 :          0 :                                         plt_err("Representor port action set failed");
     541                 :          0 :                                         goto err_exit;
     542                 :            :                                 }
     543                 :            :                         } else {
     544         [ #  # ]:          0 :                                 if (actions->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT)
     545                 :          0 :                                         continue;
     546                 :            :                                 /* Normal port as represented_port as action not supported*/
     547                 :            :                                 return -ENOTSUP;
     548                 :            :                         }
     549                 :            :                         break;
     550                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
     551                 :            :                         /* No port ID action on representor ethdevs */
     552         [ #  # ]:          0 :                         if (is_rep)
     553                 :          0 :                                 continue;
     554                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
     555                 :          0 :                         in_actions[i].conf = actions->conf;
     556                 :            :                         act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf;
     557                 :            :                         port_act = (const struct rte_flow_action_port_id *)actions->conf;
     558         [ #  # ]:          0 :                         if (rte_eth_dev_get_name_by_port(
     559                 :            :                                     actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
     560                 :            :                                             act_ethdev->port_id :
     561                 :          0 :                                             port_act->id,
     562                 :            :                                     if_name)) {
     563                 :          0 :                                 plt_err("Name not found for output port id");
     564                 :          0 :                                 goto err_exit;
     565                 :            :                         }
     566                 :          0 :                         portid_eth_dev = rte_eth_dev_allocated(if_name);
     567         [ #  # ]:          0 :                         if (!portid_eth_dev) {
     568                 :          0 :                                 plt_err("eth_dev not found for output port id");
     569                 :          0 :                                 goto err_exit;
     570                 :            :                         }
     571                 :            : 
     572         [ #  # ]:          0 :                         if (cnxk_ethdev_is_representor(if_name)) {
     573                 :          0 :                                 plt_rep_dbg("Representor port %d act port %d", port_act->id,
     574                 :            :                                             act_ethdev->port_id);
     575         [ #  # ]:          0 :                                 if (representor_portid_action(in_actions, portid_eth_dev,
     576                 :            :                                                               dst_pf_func, has_tunnel_pattern,
     577                 :            :                                                               free_allocs, &i)) {
     578                 :          0 :                                         plt_err("Representor port action set failed");
     579                 :          0 :                                         goto err_exit;
     580                 :            :                                 }
     581                 :            :                         } else {
     582                 :          0 :                                 if (strcmp(portid_eth_dev->device->driver->name,
     583         [ #  # ]:          0 :                                            eth_dev->device->driver->name) != 0) {
     584                 :          0 :                                         plt_err("Output port not under same driver");
     585                 :          0 :                                         goto err_exit;
     586                 :            :                                 }
     587                 :            : 
     588                 :          0 :                                 hw_dst = portid_eth_dev->data->dev_private;
     589                 :          0 :                                 roc_npc_mcam_default_rule_action_get(&hw_dst->npc,
     590                 :            :                                                                      npc_default_action);
     591                 :            :                                 roc_npc_dst = &hw_dst->npc;
     592                 :          0 :                                 *dst_pf_func = roc_npc_dst->pf_func;
     593                 :            :                         }
     594                 :            :                         break;
     595                 :            : 
     596                 :          0 :                 case RTE_FLOW_ACTION_TYPE_QUEUE:
     597                 :          0 :                         act_q = (const struct rte_flow_action_queue *)actions->conf;
     598                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
     599                 :          0 :                         in_actions[i].conf = actions->conf;
     600                 :          0 :                         break;
     601                 :            : 
     602                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
     603                 :            :                         /* No RSS action on representor ethdevs */
     604         [ #  # ]:          0 :                         if (is_rep)
     605                 :          0 :                                 continue;
     606                 :          0 :                         rc = npc_rss_action_validate(eth_dev, attr, actions);
     607         [ #  # ]:          0 :                         if (rc)
     608                 :          0 :                                 goto err_exit;
     609                 :            : 
     610                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
     611                 :          0 :                         in_actions[i].conf = actions->conf;
     612                 :          0 :                         npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg,
     613         [ #  # ]:          0 :                                             eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);
     614                 :            :                         break;
     615                 :            : 
     616                 :          0 :                 case RTE_FLOW_ACTION_TYPE_SECURITY:
     617                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
     618                 :          0 :                         in_actions[i].conf = actions->conf;
     619                 :          0 :                         in_actions[i].is_non_inp = flow_flags & CNXK_FLOW_NON_INPLACE;
     620                 :          0 :                         in_actions[i].no_sec_action = flow_flags & CNXK_FLOW_NO_SEC_ACTION;
     621                 :          0 :                         break;
     622                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
     623                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
     624                 :          0 :                         break;
     625                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
     626                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
     627                 :          0 :                         in_actions[i].conf = actions->conf;
     628                 :          0 :                         break;
     629                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
     630                 :          0 :                         in_actions[i].type =
     631                 :            :                                 ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
     632                 :          0 :                         in_actions[i].conf = actions->conf;
     633                 :          0 :                         break;
     634                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
     635                 :          0 :                         in_actions[i].type =
     636                 :            :                                 ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
     637                 :          0 :                         in_actions[i].conf = actions->conf;
     638                 :          0 :                         break;
     639                 :          0 :                 case RTE_FLOW_ACTION_TYPE_METER:
     640                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_METER;
     641                 :          0 :                         in_actions[i].conf = actions->conf;
     642                 :          0 :                         break;
     643                 :          0 :                 case RTE_FLOW_ACTION_TYPE_AGE:
     644                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE;
     645                 :          0 :                         in_actions[i].conf = actions->conf;
     646                 :          0 :                         break;
     647                 :          0 :                 case RTE_FLOW_ACTION_TYPE_SAMPLE:
     648                 :          0 :                         act_sample = actions->conf;
     649                 :          0 :                         in_sample_actions->ratio = act_sample->ratio;
     650                 :          0 :                         rc = roc_npc_parse_sample_subaction(eth_dev, act_sample->actions,
     651                 :            :                                                             in_sample_actions);
     652         [ #  # ]:          0 :                         if (rc) {
     653                 :          0 :                                 plt_err("Sample subaction parsing failed.");
     654                 :          0 :                                 goto err_exit;
     655                 :            :                         }
     656                 :            : 
     657                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SAMPLE;
     658                 :          0 :                         in_actions[i].conf = in_sample_actions;
     659                 :          0 :                         break;
     660                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
     661                 :          0 :                         continue;
     662                 :          0 :                 default:
     663                 :          0 :                         plt_npc_dbg("Action is not supported = %d", actions->type);
     664                 :          0 :                         goto err_exit;
     665                 :            :                 }
     666                 :          0 :                 i++;
     667                 :            :         }
     668                 :            : 
     669         [ #  # ]:          0 :         if (!is_vf_action && act_q) {
     670                 :          0 :                 rq = act_q->index;
     671         [ #  # ]:          0 :                 if (rq >= eth_dev->data->nb_rx_queues) {
     672                 :          0 :                         plt_npc_dbg("Invalid queue index");
     673                 :          0 :                         goto err_exit;
     674                 :            :                 }
     675                 :            :         }
     676                 :          0 :         in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
     677                 :          0 :         return 0;
     678                 :            : 
     679                 :            : err_exit:
     680                 :            :         return -EINVAL;
     681                 :            : }
     682                 :            : 
     683                 :            : static int
     684                 :          0 : cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern[],
     685                 :            :                  struct roc_npc_item_info in_pattern[], uint8_t *has_tunnel_pattern, bool is_rep,
     686                 :            :                  uint8_t *rep_pattern, uint64_t *free_allocs)
     687                 :            : {
     688                 :            :         const struct rte_flow_item_ethdev *rep_eth_dev;
     689                 :            :         struct rte_eth_dev *portid_eth_dev;
     690                 :            :         char if_name[RTE_ETH_NAME_MAX_LEN];
     691                 :            :         struct cnxk_eth_dev *hw_dst;
     692                 :            :         struct cnxk_rep_dev *rdev;
     693                 :            :         struct cnxk_eth_dev *dev;
     694                 :            :         struct roc_npc *npc;
     695                 :            :         int i = 0, j = 0;
     696                 :            : 
     697         [ #  # ]:          0 :         if (!is_rep) {
     698                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
     699                 :          0 :                 npc = &dev->npc;
     700                 :            :         } else {
     701                 :            :                 rdev = cnxk_rep_pmd_priv(eth_dev);
     702                 :          0 :                 npc = &rdev->parent_dev->npc;
     703                 :            : 
     704                 :          0 :                 npc->rep_npc = npc;
     705                 :          0 :                 npc->rep_port_id = rdev->port_id;
     706                 :          0 :                 npc->rep_pf_func = rdev->hw_func;
     707                 :            :         }
     708                 :            : 
     709         [ #  # ]:          0 :         while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
     710                 :          0 :                 in_pattern[i].spec = pattern->spec;
     711                 :          0 :                 in_pattern[i].last = pattern->last;
     712                 :          0 :                 in_pattern[i].mask = pattern->mask;
     713                 :          0 :                 in_pattern[i].type = term[pattern->type].item_type;
     714                 :          0 :                 in_pattern[i].size = term[pattern->type].item_size;
     715         [ #  # ]:          0 :                 if (pattern->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT ||
     716                 :            :                     pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) {
     717                 :            :                         rep_eth_dev = (const struct rte_flow_item_ethdev *)pattern->spec;
     718         [ #  # ]:          0 :                         if (rte_eth_dev_get_name_by_port(rep_eth_dev->port_id, if_name)) {
     719                 :          0 :                                 plt_err("Name not found for output port id");
     720                 :          0 :                                 goto fail;
     721                 :            :                         }
     722                 :          0 :                         portid_eth_dev = rte_eth_dev_allocated(if_name);
     723         [ #  # ]:          0 :                         if (!portid_eth_dev) {
     724                 :          0 :                                 plt_err("eth_dev not found for output port id");
     725                 :          0 :                                 goto fail;
     726                 :            :                         }
     727                 :          0 :                         *rep_pattern = pattern->type;
     728         [ #  # ]:          0 :                         if (cnxk_ethdev_is_representor(if_name)) {
     729                 :            :                                 /* Case where represented port not part of same
     730                 :            :                                  * app and represented by a representor port.
     731                 :            :                                  */
     732                 :            :                                 struct cnxk_rep_dev *rep_dev;
     733                 :            :                                 struct cnxk_eswitch_dev *eswitch_dev;
     734                 :            : 
     735                 :            :                                 rep_dev = cnxk_rep_pmd_priv(portid_eth_dev);
     736                 :          0 :                                 eswitch_dev = rep_dev->parent_dev;
     737                 :          0 :                                 npc->rep_npc = &eswitch_dev->npc;
     738                 :          0 :                                 npc->rep_port_id = rep_eth_dev->port_id;
     739                 :          0 :                                 npc->rep_pf_func = rep_dev->hw_func;
     740                 :            : 
     741         [ #  # ]:          0 :                                 if (pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) {
     742                 :            :                                         struct rte_flow_item_vlan *vlan;
     743                 :            : 
     744                 :          0 :                                         npc->rep_pf_func = eswitch_dev->npc.pf_func;
     745                 :            :                                         /* Add VLAN pattern corresponding to rep_id */
     746                 :          0 :                                         i++;
     747                 :          0 :                                         vlan = plt_zmalloc(sizeof(struct rte_flow_item_vlan), 0);
     748         [ #  # ]:          0 :                                         if (!vlan) {
     749                 :          0 :                                                 plt_err("error allocation memory");
     750                 :          0 :                                                 return -ENOMEM;
     751                 :            :                                         }
     752                 :            : 
     753         [ #  # ]:          0 :                                         while (free_allocs[j] != 0)
     754                 :          0 :                                                 j++;
     755                 :          0 :                                         free_allocs[j] = (uint64_t)vlan;
     756                 :            : 
     757                 :          0 :                                         npc->rep_rx_channel = ROC_ESWITCH_LBK_CHAN;
     758                 :          0 :                                         vlan->hdr.vlan_tci = RTE_BE16(rep_dev->rep_id);
     759                 :          0 :                                         in_pattern[i].spec = (struct rte_flow_item_vlan *)vlan;
     760                 :          0 :                                         in_pattern[i].last = NULL;
     761                 :          0 :                                         in_pattern[i].mask = &rte_flow_item_vlan_mask;
     762                 :          0 :                                         in_pattern[i].type =
     763                 :            :                                                 term[RTE_FLOW_ITEM_TYPE_VLAN].item_type;
     764                 :          0 :                                         in_pattern[i].size =
     765                 :            :                                                 term[RTE_FLOW_ITEM_TYPE_VLAN].item_size;
     766                 :            :                                 }
     767                 :          0 :                                 *rep_pattern |= 1 << IS_REP_BIT;
     768                 :          0 :                                 plt_rep_dbg("Represented port %d act port %d rep_dev->hw_func 0x%x",
     769                 :            :                                             rep_eth_dev->port_id, eth_dev->data->port_id,
     770                 :            :                                             rep_dev->hw_func);
     771                 :            :                         } else {
     772                 :          0 :                                 if (strcmp(portid_eth_dev->device->driver->name,
     773         [ #  # ]:          0 :                                            eth_dev->device->driver->name) != 0) {
     774                 :          0 :                                         plt_err("Output port not under same driver");
     775                 :          0 :                                         goto fail;
     776                 :            :                                 }
     777                 :            :                                 /* Normal port as port_representor pattern can't be supported */
     778         [ #  # ]:          0 :                                 if (pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR)
     779                 :            :                                         return -ENOTSUP;
     780                 :            :                                 /* Case where represented port part of same app
     781                 :            :                                  * as PF.
     782                 :            :                                  */
     783                 :          0 :                                 hw_dst = portid_eth_dev->data->dev_private;
     784                 :          0 :                                 npc->rep_npc = &hw_dst->npc;
     785                 :          0 :                                 npc->rep_port_id = rep_eth_dev->port_id;
     786                 :          0 :                                 npc->rep_pf_func = hw_dst->npc.pf_func;
     787                 :            :                         }
     788                 :            :                 }
     789                 :            : 
     790         [ #  # ]:          0 :                 if (pattern->type == RTE_FLOW_ITEM_TYPE_VXLAN ||
     791         [ #  # ]:          0 :                     pattern->type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE ||
     792                 :            :                     pattern->type == RTE_FLOW_ITEM_TYPE_GRE)
     793                 :          0 :                         *has_tunnel_pattern = pattern->type;
     794                 :            : 
     795                 :          0 :                 pattern++;
     796                 :          0 :                 i++;
     797                 :            :         }
     798                 :          0 :         in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
     799                 :          0 :         return 0;
     800                 :            : fail:
     801                 :            :         return -EINVAL;
     802                 :            : }
     803                 :            : 
     804                 :            : static int
     805                 :          0 : cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     806                 :            :                    const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
     807                 :            :                    struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[],
     808                 :            :                    struct roc_npc_action in_actions[],
     809                 :            :                    struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
     810                 :            :                    uint16_t *dst_pf_func, uint64_t *def_action, bool is_rep, uint64_t *free_allocs,
     811                 :            :                    uint32_t flow_flags)
     812                 :            : {
     813                 :          0 :         uint8_t has_tunnel_pattern = 0, rep_pattern = 0;
     814                 :            :         int rc;
     815                 :            : 
     816                 :          0 :         in_attr->priority = attr->priority;
     817                 :          0 :         in_attr->ingress = attr->ingress;
     818                 :          0 :         in_attr->egress = attr->egress;
     819                 :            : 
     820                 :          0 :         rc = cnxk_map_pattern(eth_dev, pattern, in_pattern, &has_tunnel_pattern, is_rep,
     821                 :            :                               &rep_pattern, free_allocs);
     822         [ #  # ]:          0 :         if (rc) {
     823                 :          0 :                 plt_err("Failed to map pattern list");
     824                 :          0 :                 return rc;
     825                 :            :         }
     826                 :            : 
     827         [ #  # ]:          0 :         if (attr->transfer) {
     828                 :            :                 /* rep_pattern is used to identify if RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
     829                 :            :                  * OR RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR is defined + if pattern's portid is
     830                 :            :                  * normal port or representor port.
     831                 :            :                  * For normal port_id, rep_pattern = pattern-> type
     832                 :            :                  * For representor port, rep_pattern = pattern-> type | 1 << IS_REP_BIT
     833                 :            :                  */
     834   [ #  #  #  # ]:          0 :                 if (is_rep || rep_pattern) {
     835   [ #  #  #  # ]:          0 :                         if (rep_pattern == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT ||
     836                 :            :                             ((rep_pattern & 0x7f) == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR))
     837                 :            :                                 /* If pattern is port_representor or pattern has normal port as
     838                 :            :                                  * represented port, install ingress rule.
     839                 :            :                                  */
     840                 :          0 :                                 in_attr->ingress = attr->transfer;
     841                 :            :                         else
     842                 :          0 :                                 in_attr->egress = attr->transfer;
     843                 :            :                 } else {
     844                 :          0 :                         in_attr->ingress = attr->transfer;
     845                 :            :                 }
     846                 :            :         }
     847                 :            : 
     848                 :          0 :         return cnxk_map_actions(eth_dev, attr, actions, in_actions, in_sample_actions, flowkey_cfg,
     849                 :            :                                 dst_pf_func, def_action, has_tunnel_pattern, is_rep, rep_pattern,
     850                 :            :                                 free_allocs, flow_flags);
     851                 :            : }
     852                 :            : 
     853                 :            : int
     854                 :          0 : cnxk_flow_validate_common(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     855                 :            :                           const struct rte_flow_item pattern[],
     856                 :            :                           const struct rte_flow_action actions[], struct rte_flow_error *error,
     857                 :            :                           bool is_rep, uint32_t flow_flags)
     858                 :            : {
     859                 :            :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
     860                 :            :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
     861                 :            :         struct roc_npc_action_sample in_sample_action;
     862                 :          0 :         uint64_t npc_default_action = 0;
     863                 :            :         struct cnxk_rep_dev *rep_dev;
     864                 :            :         struct roc_npc_attr in_attr;
     865                 :            :         uint64_t *free_allocs, sz;
     866                 :            :         struct cnxk_eth_dev *dev;
     867                 :            :         struct roc_npc_flow flow;
     868                 :          0 :         uint16_t dst_pf_func = 0;
     869                 :          0 :         uint32_t flowkey_cfg = 0;
     870                 :            :         struct roc_npc *npc = 0;
     871                 :            :         int rc, j;
     872                 :            : 
     873                 :            :         /* is_rep set for operation performed via representor ports */
     874         [ #  # ]:          0 :         if (!is_rep) {
     875                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
     876                 :          0 :                 npc = &dev->npc;
     877                 :            :                 /* Skip flow validation for MACsec. */
     878   [ #  #  #  # ]:          0 :                 if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
     879                 :          0 :                     cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL)
     880                 :            :                         return 0;
     881                 :            :         } else {
     882                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
     883                 :          0 :                 npc = &rep_dev->parent_dev->npc;
     884                 :            :         }
     885                 :            : 
     886                 :            :         memset(&flow, 0, sizeof(flow));
     887                 :            :         memset(&in_sample_action, 0, sizeof(in_sample_action));
     888                 :          0 :         flow.is_validate = true;
     889                 :            : 
     890                 :            :         sz = ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1;
     891                 :          0 :         free_allocs = plt_zmalloc(sz * sizeof(uint64_t), 0);
     892         [ #  # ]:          0 :         if (!free_allocs) {
     893                 :          0 :                 rte_flow_error_set(error, -ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     894                 :            :                                    "Failed to map flow data");
     895                 :          0 :                 return -ENOMEM;
     896                 :            :         }
     897                 :          0 :         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
     898                 :            :                                 &in_sample_action, &flowkey_cfg, &dst_pf_func, &npc_default_action,
     899                 :            :                                 is_rep, free_allocs, flow_flags);
     900         [ #  # ]:          0 :         if (rc) {
     901                 :          0 :                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     902                 :            :                                    "Failed to map flow data");
     903                 :          0 :                 goto clean;
     904                 :            :         }
     905                 :            : 
     906                 :          0 :         rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
     907                 :            : 
     908         [ #  # ]:          0 :         if (rc) {
     909                 :          0 :                 rte_flow_error_set(error, 0, rc, NULL,
     910                 :            :                                    "Flow validation failed");
     911                 :          0 :                 goto clean;
     912                 :            :         }
     913                 :          0 : clean:
     914                 :            :         /* Freeing the allocations done for additional patterns/actions */
     915   [ #  #  #  # ]:          0 :         for (j = 0; (j < (int)sz) && free_allocs[j]; j++)
     916                 :          0 :                 plt_free((void *)free_allocs[j]);
     917                 :          0 :         plt_free(free_allocs);
     918                 :            : 
     919                 :          0 :         return rc;
     920                 :            : }
     921                 :            : 
     922                 :            : static int
     923         [ #  # ]:          0 : cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     924                 :            :                    const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
     925                 :            :                    struct rte_flow_error *error)
     926                 :            : {
     927                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     928                 :            :         struct cnxk_eth_sec_sess *eth_sec = NULL;
     929                 :            :         uint32_t flow_flags = 0;
     930                 :            : 
     931         [ #  # ]:          0 :         if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY) {
     932                 :          0 :                 eth_sec = cnxk_eth_sec_sess_get_by_sess(dev, actions[0].conf);
     933         [ #  # ]:          0 :                 if (eth_sec != NULL) {
     934         [ #  # ]:          0 :                         flow_flags = eth_sec->inb_oop ? CNXK_FLOW_NON_INPLACE : 0;
     935                 :          0 :                         flow_flags |= CNXK_FLOW_NO_SEC_ACTION;
     936                 :            :                 }
     937                 :            :         }
     938                 :            : 
     939                 :          0 :         return cnxk_flow_validate_common(eth_dev, attr, pattern, actions, error, false, flow_flags);
     940                 :            : }
     941                 :            : 
     942                 :            : struct roc_npc_flow *
     943                 :          0 : cnxk_flow_create_common(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     944                 :            :                         const struct rte_flow_item pattern[],
     945                 :            :                         const struct rte_flow_action actions[], struct rte_flow_error *error,
     946                 :            :                         bool is_rep, uint32_t flow_flags)
     947                 :            : {
     948                 :          0 :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1] = {0};
     949                 :          0 :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT] = {0};
     950                 :            :         struct roc_npc_action_sample in_sample_action;
     951                 :            :         struct cnxk_rep_dev *rep_dev = NULL;
     952                 :            :         struct roc_npc_flow *flow = NULL;
     953                 :            :         struct cnxk_eth_dev *dev = NULL;
     954                 :          0 :         uint64_t npc_default_action = 0;
     955                 :            :         struct roc_npc_attr in_attr;
     956                 :            :         struct roc_npc *npc = NULL;
     957                 :            :         uint64_t *free_allocs, sz;
     958                 :          0 :         uint16_t dst_pf_func = 0;
     959                 :          0 :         int errcode = 0;
     960                 :            :         int rc, j;
     961                 :            : 
     962                 :            :         /* is_rep set for operation performed via representor ports */
     963         [ #  # ]:          0 :         if (!is_rep) {
     964                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
     965                 :          0 :                 npc = &dev->npc;
     966                 :            :         } else {
     967                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
     968                 :          0 :                 npc = &rep_dev->parent_dev->npc;
     969                 :            :         }
     970                 :            : 
     971                 :            :         sz = ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1;
     972                 :          0 :         free_allocs = plt_zmalloc(sz * sizeof(uint64_t), 0);
     973         [ #  # ]:          0 :         if (!free_allocs) {
     974                 :          0 :                 rte_flow_error_set(error, -ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     975                 :            :                                    "Failed to map flow data");
     976                 :          0 :                 return NULL;
     977                 :            :         }
     978                 :            :         memset(&in_sample_action, 0, sizeof(in_sample_action));
     979                 :            :         memset(&in_attr, 0, sizeof(struct roc_npc_attr));
     980                 :          0 :         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
     981                 :            :                                 &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func,
     982                 :            :                                 &npc_default_action, is_rep, free_allocs, flow_flags);
     983         [ #  # ]:          0 :         if (rc) {
     984                 :          0 :                 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     985                 :            :                                    "Failed to map flow data");
     986                 :          0 :                 goto clean;
     987                 :            :         }
     988                 :            : 
     989                 :          0 :         flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, dst_pf_func,
     990                 :            :                                    npc_default_action, &errcode);
     991         [ #  # ]:          0 :         if (errcode != 0) {
     992                 :          0 :                 rte_flow_error_set(error, errcode, errcode, NULL, roc_error_msg_get(errcode));
     993                 :          0 :                 goto clean;
     994                 :            :         }
     995                 :            : 
     996                 :          0 : clean:
     997                 :            :         /* Freeing the allocations done for additional patterns/actions */
     998   [ #  #  #  # ]:          0 :         for (j = 0; (j < (int)sz) && free_allocs[j]; j++)
     999                 :          0 :                 plt_free((void *)free_allocs[j]);
    1000                 :          0 :         plt_free(free_allocs);
    1001                 :            : 
    1002                 :          0 :         return flow;
    1003                 :            : }
    1004                 :            : 
    1005                 :            : int
    1006                 :          0 : cnxk_flow_destroy_common(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
    1007                 :            :                          struct rte_flow_error *error, bool is_rep)
    1008                 :            : {
    1009                 :            :         struct cnxk_rep_dev *rep_dev;
    1010                 :            :         struct cnxk_eth_dev *dev;
    1011                 :            :         struct roc_npc *npc;
    1012                 :            :         int rc;
    1013                 :            : 
    1014                 :            :         /* is_rep set for operation performed via representor ports */
    1015         [ #  # ]:          0 :         if (!is_rep) {
    1016                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
    1017                 :          0 :                 npc = &dev->npc;
    1018                 :            :         } else {
    1019                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
    1020                 :          0 :                 npc = &rep_dev->parent_dev->npc;
    1021                 :            :         }
    1022                 :            : 
    1023                 :          0 :         rc = roc_npc_flow_destroy(npc, flow);
    1024         [ #  # ]:          0 :         if (rc)
    1025                 :          0 :                 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1026                 :            :                                    "Flow Destroy failed");
    1027                 :          0 :         return rc;
    1028                 :            : }
    1029                 :            : 
    1030                 :            : int
    1031                 :          0 : cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
    1032                 :            :                   struct rte_flow_error *error)
    1033                 :            : {
    1034                 :          0 :         return cnxk_flow_destroy_common(eth_dev, flow, error, false);
    1035                 :            : }
    1036                 :            : 
    1037                 :            : int
    1038                 :          0 : cnxk_flow_flush_common(struct rte_eth_dev *eth_dev, struct rte_flow_error *error, bool is_rep)
    1039                 :            : {
    1040                 :            :         struct cnxk_rep_dev *rep_dev;
    1041                 :            :         struct cnxk_eth_dev *dev;
    1042                 :            :         struct roc_npc *npc;
    1043                 :            :         int rc;
    1044                 :            : 
    1045                 :            :         /* is_rep set for operation performed via representor ports */
    1046         [ #  # ]:          0 :         if (!is_rep) {
    1047                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
    1048                 :          0 :                 npc = &dev->npc;
    1049                 :            :         } else {
    1050                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
    1051                 :          0 :                 npc = &rep_dev->parent_dev->npc;
    1052                 :            :         }
    1053                 :            : 
    1054                 :          0 :         rc = roc_npc_mcam_free_all_resources(npc);
    1055         [ #  # ]:          0 :         if (rc) {
    1056                 :          0 :                 rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1057                 :            :                                    "Failed to flush filter");
    1058                 :          0 :                 return -rte_errno;
    1059                 :            :         }
    1060                 :            : 
    1061                 :            :         return 0;
    1062                 :            : }
    1063                 :            : 
    1064                 :            : static int
    1065                 :          0 : cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
    1066                 :            : {
    1067                 :          0 :         return cnxk_flow_flush_common(eth_dev, error, false);
    1068                 :            : }
    1069                 :            : 
    1070                 :            : int
    1071                 :          0 : cnxk_flow_query_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
    1072                 :            :                        const struct rte_flow_action *action, void *data,
    1073                 :            :                        struct rte_flow_error *error, bool is_rep)
    1074                 :            : {
    1075                 :            :         struct rte_flow_query_count *query = data;
    1076                 :            :         struct roc_npc_flow *in_flow;
    1077                 :            :         struct cnxk_rep_dev *rep_dev;
    1078                 :            :         const char *errmsg = NULL;
    1079                 :            :         struct cnxk_eth_dev *dev;
    1080                 :            :         int errcode = ENOTSUP;
    1081                 :            :         struct roc_npc *npc;
    1082                 :            :         int rc;
    1083                 :            : 
    1084         [ #  # ]:          0 :         if (flow == NULL) {
    1085                 :            :                 errmsg = "Invalid flow handle";
    1086                 :            :                 errcode = EINVAL;
    1087                 :          0 :                 goto err_exit;
    1088                 :            :         }
    1089                 :            : 
    1090                 :            :         /* is_rep set for operation performed via representor ports */
    1091         [ #  # ]:          0 :         if (!is_rep) {
    1092                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
    1093                 :          0 :                 npc = &dev->npc;
    1094                 :            :         } else {
    1095                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
    1096                 :          0 :                 npc = &rep_dev->parent_dev->npc;
    1097                 :            :         }
    1098                 :            : 
    1099                 :            :         /* Let the roc layer resolve async/template handles to the underlying
    1100                 :            :          * roc_npc_flow (NULL until committed); else treat as a sync flow.
    1101                 :            :          */
    1102                 :          0 :         in_flow = (struct roc_npc_flow *)flow;
    1103         [ #  # ]:          0 :         if (!is_rep)
    1104                 :          0 :                 roc_npc_async_flow_resolve(npc, flow, &in_flow);
    1105                 :            : 
    1106         [ #  # ]:          0 :         if (in_flow == NULL) {
    1107                 :            :                 errmsg = "Flow is not committed yet";
    1108                 :            :                 errcode = EINVAL;
    1109                 :          0 :                 goto err_exit;
    1110                 :            :         }
    1111                 :            : 
    1112         [ #  # ]:          0 :         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
    1113                 :            :                 errmsg = "Only COUNT is supported in query";
    1114                 :          0 :                 goto err_exit;
    1115                 :            :         }
    1116                 :            : 
    1117         [ #  # ]:          0 :         if (in_flow->ctr_id == NPC_COUNTER_NONE) {
    1118                 :            :                 errmsg = "Counter is not available";
    1119                 :          0 :                 goto err_exit;
    1120                 :            :         }
    1121                 :            : 
    1122         [ #  # ]:          0 :         if (in_flow->use_pre_alloc) {
    1123                 :          0 :                 rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
    1124                 :            :         } else {
    1125         [ #  # ]:          0 :                 if (roc_model_is_cn20k())
    1126                 :          0 :                         rc = roc_npc_mcam_get_stats(npc, in_flow, &query->hits);
    1127                 :            :                 else
    1128                 :          0 :                         rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
    1129                 :            :         }
    1130         [ #  # ]:          0 :         if (rc != 0) {
    1131                 :            :                 errcode = EIO;
    1132                 :            :                 errmsg = "Error reading flow counter";
    1133                 :          0 :                 goto err_exit;
    1134                 :            :         }
    1135                 :          0 :         query->hits_set = 1;
    1136                 :          0 :         query->bytes_set = 0;
    1137                 :            : 
    1138         [ #  # ]:          0 :         if (query->reset) {
    1139         [ #  # ]:          0 :                 if (in_flow->use_pre_alloc)
    1140                 :          0 :                         rc = roc_npc_inl_mcam_clear_counter(in_flow->ctr_id);
    1141                 :            :                 else
    1142                 :          0 :                         rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
    1143                 :            :         }
    1144         [ #  # ]:          0 :         if (rc != 0) {
    1145                 :            :                 errcode = EIO;
    1146                 :            :                 errmsg = "Error clearing flow counter";
    1147                 :          0 :                 goto err_exit;
    1148                 :            :         }
    1149                 :            : 
    1150                 :            :         return 0;
    1151                 :            : 
    1152                 :          0 : err_exit:
    1153                 :          0 :         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
    1154                 :            :                            NULL, errmsg);
    1155                 :          0 :         return -rte_errno;
    1156                 :            : }
    1157                 :            : 
    1158                 :            : static int
    1159                 :          0 : cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
    1160                 :            :                 const struct rte_flow_action *action, void *data, struct rte_flow_error *error)
    1161                 :            : {
    1162                 :          0 :         return cnxk_flow_query_common(eth_dev, flow, action, data, error, false);
    1163                 :            : }
    1164                 :            : 
    1165                 :            : static int
    1166                 :          0 : cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused, int enable __rte_unused,
    1167                 :            :                   struct rte_flow_error *error)
    1168                 :            : {
    1169                 :            :         /* If we support, we need to un-install the default mcam
    1170                 :            :          * entry for this port.
    1171                 :            :          */
    1172                 :            : 
    1173                 :          0 :         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1174                 :            :                            "Flow isolation not supported");
    1175                 :            : 
    1176                 :          0 :         return -rte_errno;
    1177                 :            : }
    1178                 :            : 
    1179                 :            : int
    1180                 :          0 : cnxk_flow_dev_dump_common(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
    1181                 :            :                           struct rte_flow_error *error, bool is_rep)
    1182                 :            : {
    1183                 :          0 :         struct roc_npc_flow *in_flow = NULL;
    1184                 :            :         struct cnxk_eth_dev *dev = NULL;
    1185                 :            :         struct cnxk_rep_dev *rep_dev;
    1186                 :            :         struct roc_npc *npc;
    1187                 :            : 
    1188                 :            :         /* is_rep set for operation performed via representor ports */
    1189         [ #  # ]:          0 :         if (!is_rep) {
    1190                 :            :                 dev = cnxk_eth_pmd_priv(eth_dev);
    1191                 :          0 :                 npc = &dev->npc;
    1192                 :            :         } else {
    1193                 :            :                 rep_dev = cnxk_rep_pmd_priv(eth_dev);
    1194                 :          0 :                 npc = &rep_dev->parent_dev->npc;
    1195                 :            :         }
    1196                 :            : 
    1197         [ #  # ]:          0 :         if (file == NULL) {
    1198                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1199                 :            :                                    "Invalid file");
    1200                 :          0 :                 return -rte_errno;
    1201                 :            :         }
    1202                 :            : 
    1203         [ #  # ]:          0 :         if (flow != NULL) {
    1204                 :            :                 /* Resolve async/template handles to the underlying roc_npc_flow;
    1205                 :            :                  * else treat as a sync flow.
    1206                 :            :                  */
    1207   [ #  #  #  # ]:          0 :                 if (is_rep || !roc_npc_async_flow_resolve(npc, flow, &in_flow))
    1208                 :          0 :                         in_flow = (struct roc_npc_flow *)flow;
    1209                 :            : 
    1210         [ #  # ]:          0 :                 if (in_flow == NULL)
    1211                 :          0 :                         return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1212                 :            :                                                   "flow is not committed yet");
    1213                 :            : 
    1214                 :          0 :                 roc_npc_flow_mcam_dump(file, npc, in_flow);
    1215                 :          0 :                 return 0;
    1216                 :            :         }
    1217                 :            : 
    1218                 :          0 :         roc_npc_flow_dump(file, npc, -1);
    1219                 :            : 
    1220                 :          0 :         return 0;
    1221                 :            : }
    1222                 :            : /* Configure async flow queues for the port. */
    1223                 :            : int
    1224         [ #  # ]:          0 : cnxk_flow_configure(struct rte_eth_dev *eth_dev, const struct rte_flow_port_attr *port_attr,
    1225                 :            :                     uint16_t nb_queue, const struct rte_flow_queue_attr *queue_attr[],
    1226                 :            :                     struct rte_flow_error *err)
    1227                 :            : {
    1228                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1229                 :            :         const struct roc_npc_flow_queue_attr **rptrs = NULL;
    1230                 :            :         struct roc_npc_flow_queue_attr *rattr = NULL;
    1231                 :          0 :         struct roc_npc *npc = &dev->npc;
    1232                 :            :         uint16_t i;
    1233                 :            :         int rc;
    1234                 :            : 
    1235                 :            :         RTE_SET_USED(port_attr);
    1236                 :            : 
    1237                 :            :         /* Translate the rte queue attributes into roc_npc types; the roc
    1238                 :            :          * engine validates nb_queue == 0 and a NULL queue_attr.
    1239                 :            :          */
    1240         [ #  # ]:          0 :         if (nb_queue != 0 && queue_attr != NULL) {
    1241                 :          0 :                 rattr = plt_zmalloc(nb_queue * sizeof(*rattr), 0);
    1242         [ #  # ]:          0 :                 if (rattr == NULL)
    1243                 :          0 :                         return rte_flow_error_set(err, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
    1244                 :            :                                                   NULL, "Failed to allocate flow queues");
    1245                 :            : 
    1246                 :          0 :                 rptrs = plt_zmalloc(nb_queue * sizeof(*rptrs), 0);
    1247         [ #  # ]:          0 :                 if (rptrs == NULL) {
    1248                 :          0 :                         plt_free(rattr);
    1249                 :          0 :                         return rte_flow_error_set(err, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
    1250                 :            :                                                   NULL, "Failed to allocate flow queues");
    1251                 :            :                 }
    1252         [ #  # ]:          0 :                 for (i = 0; i < nb_queue; i++) {
    1253         [ #  # ]:          0 :                         if (queue_attr[i] != NULL) {
    1254                 :          0 :                                 rattr[i].size = queue_attr[i]->size;
    1255                 :          0 :                                 rptrs[i] = &rattr[i];
    1256                 :            :                         } else {
    1257                 :          0 :                                 rptrs[i] = NULL;
    1258                 :            :                         }
    1259                 :            :                 }
    1260                 :            :         }
    1261                 :            : 
    1262                 :          0 :         rc = roc_npc_flow_configure(npc, nb_queue, rptrs);
    1263                 :            : 
    1264                 :          0 :         plt_free(rattr);
    1265                 :          0 :         plt_free(rptrs);
    1266                 :            : 
    1267         [ #  # ]:          0 :         if (rc)
    1268                 :          0 :                 return rte_flow_error_set(err, -rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1269                 :            :                                           "Failed to configure flow queues");
    1270                 :            :         return 0;
    1271                 :            : }
    1272                 :            : 
    1273                 :            : /* Deep-copy a spec/last/mask/conf payload into template-owned memory. */
    1274                 :            : static int
    1275                 :          0 : cnxk_flow_dup_conf(void **copies, uint16_t *nb_copies, const void *src, size_t sz, const void **dst)
    1276                 :            : {
    1277                 :            :         void *copy;
    1278                 :            : 
    1279         [ #  # ]:          0 :         if (src == NULL || sz == 0) {
    1280                 :          0 :                 *dst = NULL;
    1281                 :          0 :                 return 0;
    1282                 :            :         }
    1283                 :          0 :         copy = plt_zmalloc(sz, 0);
    1284         [ #  # ]:          0 :         if (copy == NULL)
    1285                 :            :                 return -ENOMEM;
    1286                 :            :         memcpy(copy, src, sz);
    1287                 :          0 :         copies[(*nb_copies)++] = copy;
    1288                 :          0 :         *dst = copy;
    1289                 :          0 :         return 0;
    1290                 :            : }
    1291                 :            : 
    1292                 :            : struct rte_flow_pattern_template *
    1293         [ #  # ]:          0 : cnxk_flow_pattern_template_create(struct rte_eth_dev *eth_dev,
    1294                 :            :                                   const struct rte_flow_pattern_template_attr *attr,
    1295                 :            :                                   const struct rte_flow_item pattern[],
    1296                 :            :                                   struct rte_flow_error *error)
    1297                 :            : {
    1298                 :            :         const char *errmsg = "Failed to allocate pattern template";
    1299                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1300                 :            :         struct cnxk_flow_pattern_template *tmpl = NULL;
    1301                 :            :         struct roc_npc_pattern_template_attr roc_attr;
    1302                 :            :         struct roc_npc_item_info *roc_pattern = NULL;
    1303                 :            :         int i, nb_items = 0, errcode = ENOMEM;
    1304                 :          0 :         struct roc_npc *npc = &dev->npc;
    1305                 :            :         int roc_err;
    1306                 :            : 
    1307         [ #  # ]:          0 :         if (attr == NULL) {
    1308                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1309                 :            :                                    "NULL template attr");
    1310                 :          0 :                 return NULL;
    1311                 :            :         }
    1312                 :            : 
    1313         [ #  # ]:          0 :         if (pattern == NULL) {
    1314                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1315                 :            :                                    "NULL pattern");
    1316                 :          0 :                 return NULL;
    1317                 :            :         }
    1318                 :            : 
    1319         [ #  # ]:          0 :         while (pattern[nb_items].type != RTE_FLOW_ITEM_TYPE_END)
    1320                 :          0 :                 nb_items++;
    1321                 :            : 
    1322                 :            :         /* Reject oversized templates; rules are built into fixed-size stack
    1323                 :            :          * arrays (combined_items[ROC_NPC_ITEM_TYPE_END + 1]).
    1324                 :            :          */
    1325         [ #  # ]:          0 :         if (nb_items > ROC_NPC_ITEM_TYPE_END) {
    1326                 :            :                 errcode = ENOTSUP;
    1327                 :            :                 errmsg = "too many pattern items for hardware";
    1328                 :          0 :                 goto err_nomem;
    1329                 :            :         }
    1330                 :            : 
    1331                 :          0 :         tmpl = plt_zmalloc(sizeof(*tmpl), 0);
    1332         [ #  # ]:          0 :         if (tmpl == NULL)
    1333                 :          0 :                 goto err_nomem;
    1334                 :            : 
    1335                 :          0 :         tmpl->attr = *attr;
    1336                 :          0 :         tmpl->nb_items = nb_items;
    1337                 :            : 
    1338                 :          0 :         tmpl->pattern = plt_zmalloc((nb_items + 1) * sizeof(struct rte_flow_item), 0);
    1339         [ #  # ]:          0 :         if (tmpl->pattern == NULL)
    1340                 :          0 :                 goto err_free;
    1341                 :            : 
    1342                 :            :         /* At most 3 payload copies (spec/last/mask) per item. */
    1343                 :          0 :         tmpl->copies = plt_zmalloc(3 * (nb_items + 1) * sizeof(void *), 0);
    1344         [ #  # ]:          0 :         if (tmpl->copies == NULL)
    1345                 :          0 :                 goto err_free;
    1346                 :            : 
    1347         [ #  # ]:          0 :         for (i = 0; i < nb_items; i++) {
    1348                 :          0 :                 enum rte_flow_item_type t = pattern[i].type;
    1349         [ #  # ]:          0 :                 size_t sz = (t < (int)RTE_DIM(term)) ? term[t].item_size : 0;
    1350                 :            : 
    1351                 :            :                 /* Reject unrepresentable item types (sz 0), which would drop
    1352                 :            :                  * spec/last/mask. VOID/ANY legitimately carry no payload.
    1353                 :            :                  */
    1354   [ #  #  #  # ]:          0 :                 if (t != RTE_FLOW_ITEM_TYPE_VOID && t != RTE_FLOW_ITEM_TYPE_ANY && sz == 0) {
    1355                 :            :                         errcode = ENOTSUP;
    1356                 :            :                         errmsg = "unsupported pattern item type in template";
    1357                 :          0 :                         goto err_free;
    1358                 :            :                 }
    1359                 :            : 
    1360                 :            :                 /* Reject items with nested variable-length payloads; a flat
    1361                 :            :                  * memcpy would retain a dangling pointer into caller memory.
    1362                 :            :                  */
    1363         [ #  # ]:          0 :                 if (t == RTE_FLOW_ITEM_TYPE_RAW) {
    1364                 :            :                         errcode = ENOTSUP;
    1365                 :            :                         errmsg = "Item type with nested pointers is not supported "
    1366                 :            :                                  "in pattern template (e.g. RAW)";
    1367                 :          0 :                         goto err_free;
    1368                 :            :                 }
    1369                 :            : 
    1370                 :          0 :                 tmpl->pattern[i].type = t;
    1371         [ #  # ]:          0 :                 if (cnxk_flow_dup_conf(tmpl->copies, &tmpl->nb_copies, pattern[i].spec, sz,
    1372         [ #  # ]:          0 :                                        &tmpl->pattern[i].spec) ||
    1373                 :          0 :                     cnxk_flow_dup_conf(tmpl->copies, &tmpl->nb_copies, pattern[i].last, sz,
    1374         [ #  # ]:          0 :                                        &tmpl->pattern[i].last) ||
    1375                 :          0 :                     cnxk_flow_dup_conf(tmpl->copies, &tmpl->nb_copies, pattern[i].mask, sz,
    1376                 :          0 :                                        &tmpl->pattern[i].mask))
    1377                 :          0 :                         goto err_free;
    1378                 :            :         }
    1379                 :          0 :         tmpl->pattern[nb_items].type = RTE_FLOW_ITEM_TYPE_END;
    1380                 :          0 :         tmpl->roc_tmpl = NULL;
    1381                 :          0 :         tmpl->refcnt = 0;
    1382                 :            : 
    1383                 :          0 :         roc_pattern = plt_zmalloc((nb_items + 1) * sizeof(*roc_pattern), 0);
    1384         [ #  # ]:          0 :         if (roc_pattern == NULL)
    1385                 :          0 :                 goto err_free;
    1386                 :            : 
    1387         [ #  # ]:          0 :         for (i = 0; i < nb_items; i++) {
    1388                 :          0 :                 enum rte_flow_item_type t = tmpl->pattern[i].type;
    1389         [ #  # ]:          0 :                 size_t sz = (t < (int)RTE_DIM(term)) ? term[t].item_size : 0;
    1390                 :            : 
    1391                 :          0 :                 roc_pattern[i].type =
    1392         [ #  # ]:          0 :                         (t < (int)RTE_DIM(term)) ? term[t].item_type : ROC_NPC_ITEM_TYPE_VOID;
    1393                 :          0 :                 roc_pattern[i].size = sz;
    1394                 :          0 :                 roc_pattern[i].spec = tmpl->pattern[i].spec;
    1395                 :          0 :                 roc_pattern[i].last = tmpl->pattern[i].last;
    1396                 :          0 :                 roc_pattern[i].mask = tmpl->pattern[i].mask;
    1397                 :            :         }
    1398                 :          0 :         roc_pattern[nb_items].type = ROC_NPC_ITEM_TYPE_END;
    1399                 :            : 
    1400                 :            :         memset(&roc_attr, 0, sizeof(roc_attr));
    1401                 :          0 :         roc_attr.relaxed_matching = attr->relaxed_matching;
    1402                 :          0 :         roc_attr.ingress = attr->ingress;
    1403                 :          0 :         roc_attr.egress = attr->egress;
    1404                 :          0 :         roc_attr.transfer = attr->transfer;
    1405                 :            : 
    1406                 :          0 :         roc_err = 0;
    1407                 :          0 :         tmpl->roc_tmpl = roc_npc_pattern_template_create(npc, &roc_attr, roc_pattern, &roc_err);
    1408         [ #  # ]:          0 :         if (tmpl->roc_tmpl == NULL) {
    1409         [ #  # ]:          0 :                 errcode = (roc_err < 0) ? -roc_err : ENOMEM;
    1410                 :            :                 errmsg = "Failed to create ROC pattern template";
    1411                 :          0 :                 goto err_free;
    1412                 :            :         }
    1413                 :            : 
    1414                 :          0 :         plt_free(roc_pattern);
    1415                 :            : 
    1416                 :          0 :         return (struct rte_flow_pattern_template *)tmpl;
    1417                 :            : 
    1418                 :          0 : err_free:
    1419                 :          0 :         plt_free(roc_pattern);
    1420                 :            :         if (tmpl != NULL) {
    1421                 :            :                 uint16_t j;
    1422         [ #  # ]:          0 :                 if (tmpl->roc_tmpl != NULL)
    1423                 :          0 :                         roc_npc_pattern_template_destroy(npc, tmpl->roc_tmpl);
    1424         [ #  # ]:          0 :                 for (j = 0; j < tmpl->nb_copies; j++)
    1425                 :          0 :                         plt_free(tmpl->copies[j]);
    1426                 :          0 :                 plt_free(tmpl->copies);
    1427                 :          0 :                 plt_free(tmpl->pattern);
    1428                 :          0 :                 plt_free(tmpl);
    1429                 :            :         }
    1430                 :          0 : err_nomem:
    1431                 :          0 :         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, errmsg);
    1432                 :          0 :         return NULL;
    1433                 :            : }
    1434                 :            : 
    1435                 :            : int
    1436         [ #  # ]:          0 : cnxk_flow_pattern_template_destroy(struct rte_eth_dev *eth_dev,
    1437                 :            :                                    struct rte_flow_pattern_template *templ,
    1438                 :            :                                    struct rte_flow_error *error)
    1439                 :            : {
    1440                 :            :         struct cnxk_flow_pattern_template *tmpl = (struct cnxk_flow_pattern_template *)templ;
    1441                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1442                 :          0 :         struct roc_npc *npc = &dev->npc;
    1443                 :            :         uint16_t i;
    1444                 :            :         int rc;
    1445                 :            : 
    1446         [ #  # ]:          0 :         if (tmpl == NULL)
    1447                 :            :                 return 0;
    1448                 :            : 
    1449         [ #  # ]:          0 :         if (tmpl->refcnt != 0)
    1450                 :          0 :                 return rte_flow_error_set(error, EBUSY, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1451                 :            :                                           "pattern template still in use by a table");
    1452                 :            : 
    1453                 :          0 :         rc = roc_npc_pattern_template_destroy(npc, tmpl->roc_tmpl);
    1454         [ #  # ]:          0 :         if (rc)
    1455                 :          0 :                 return rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1456                 :            :                                           "failed to destroy ROC pattern template");
    1457                 :            : 
    1458         [ #  # ]:          0 :         for (i = 0; i < tmpl->nb_copies; i++)
    1459                 :          0 :                 plt_free(tmpl->copies[i]);
    1460                 :          0 :         plt_free(tmpl->copies);
    1461                 :          0 :         plt_free(tmpl->pattern);
    1462                 :          0 :         plt_free(tmpl);
    1463                 :          0 :         return 0;
    1464                 :            : }
    1465                 :            : /* Size of an action's conf for the v1-supported set; -1 = unsupported. */
    1466                 :            : static int
    1467                 :            : cnxk_flow_action_conf_size(enum rte_flow_action_type type)
    1468                 :            : {
    1469                 :            :         switch (type) {
    1470                 :            :         case RTE_FLOW_ACTION_TYPE_VOID:
    1471                 :            :         case RTE_FLOW_ACTION_TYPE_DROP:
    1472                 :            :         case RTE_FLOW_ACTION_TYPE_PF:
    1473                 :            :         case RTE_FLOW_ACTION_TYPE_FLAG:
    1474                 :            :         case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
    1475                 :            :         case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
    1476                 :            :                 return 0; /* no conf */
    1477                 :            :         case RTE_FLOW_ACTION_TYPE_QUEUE:
    1478                 :            :                 return sizeof(struct rte_flow_action_queue);
    1479                 :            :         case RTE_FLOW_ACTION_TYPE_VF:
    1480                 :            :                 return sizeof(struct rte_flow_action_vf);
    1481                 :            :         case RTE_FLOW_ACTION_TYPE_MARK:
    1482                 :            :                 return sizeof(struct rte_flow_action_mark);
    1483                 :            :         case RTE_FLOW_ACTION_TYPE_COUNT:
    1484                 :            :                 return sizeof(struct rte_flow_action_count);
    1485                 :            :         case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
    1486                 :            :                 return sizeof(struct rte_flow_action_of_push_vlan);
    1487                 :            :         case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
    1488                 :            :                 return sizeof(struct rte_flow_action_of_set_vlan_vid);
    1489                 :            :         case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
    1490                 :            :                 return sizeof(struct rte_flow_action_of_set_vlan_pcp);
    1491                 :            :         case RTE_FLOW_ACTION_TYPE_AGE:
    1492                 :            :                 return sizeof(struct rte_flow_action_age);
    1493                 :            :         case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
    1494                 :            :         case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
    1495                 :            :                 return sizeof(struct rte_flow_action_ethdev);
    1496                 :            :         case RTE_FLOW_ACTION_TYPE_PORT_ID:
    1497                 :            :                 return sizeof(struct rte_flow_action_port_id);
    1498                 :            :         default:
    1499                 :            :                 return -1;
    1500                 :            :         }
    1501                 :            : }
    1502                 :            : 
    1503                 :            : /* Deep-copy an action conf. RSS nests queue[]/key[] pointers, so pack them
    1504                 :            :  * into one blob and fix the pointers; other confs use a flat memcpy.
    1505                 :            :  */
    1506                 :            : static void *
    1507                 :          0 : cnxk_flow_dup_action_conf(const struct rte_flow_action *act)
    1508                 :            : {
    1509         [ #  # ]:          0 :         if (act->conf == NULL)
    1510                 :            :                 return NULL;
    1511                 :            : 
    1512         [ #  # ]:          0 :         if (act->type == RTE_FLOW_ACTION_TYPE_RSS) {
    1513                 :            :                 const struct rte_flow_action_rss *rss = act->conf;
    1514                 :            :                 size_t rss_blob_bytes = sizeof(*rss);
    1515                 :          0 :                 size_t rss_queue_bytes = (size_t)rss->queue_num * sizeof(uint16_t);
    1516                 :          0 :                 size_t rss_key_bytes = rss->key_len;
    1517                 :            :                 struct rte_flow_action_rss *rss_copy;
    1518                 :            :                 uint8_t *rss_blob;
    1519                 :            : 
    1520                 :            :                 /* Reject a non-zero length paired with a NULL pointer, which
    1521                 :            :                  * would make the memcpy below dereference NULL.
    1522                 :            :                  */
    1523   [ #  #  #  #  :          0 :                 if ((rss_queue_bytes && rss->queue == NULL) || (rss_key_bytes && rss->key == NULL))
             #  #  #  # ]
    1524                 :            :                         return NULL;
    1525                 :            : 
    1526                 :          0 :                 rss_blob = plt_zmalloc(rss_blob_bytes + rss_queue_bytes + rss_key_bytes, 0);
    1527         [ #  # ]:          0 :                 if (rss_blob == NULL)
    1528                 :            :                         return NULL;
    1529                 :            :                 rss_copy = (struct rte_flow_action_rss *)rss_blob;
    1530                 :          0 :                 *rss_copy = *rss;
    1531         [ #  # ]:          0 :                 if (rss_queue_bytes) {
    1532                 :          0 :                         memcpy(rss_blob + rss_blob_bytes, rss->queue, rss_queue_bytes);
    1533                 :          0 :                         rss_copy->queue = (const uint16_t *)(rss_blob + rss_blob_bytes);
    1534                 :            :                 } else {
    1535                 :          0 :                         rss_copy->queue = NULL;
    1536                 :            :                 }
    1537         [ #  # ]:          0 :                 if (rss_key_bytes) {
    1538                 :          0 :                         memcpy(rss_blob + rss_blob_bytes + rss_queue_bytes, rss->key,
    1539                 :            :                                rss_key_bytes);
    1540                 :          0 :                         rss_copy->key =
    1541                 :            :                                 (const uint8_t *)(rss_blob + rss_blob_bytes + rss_queue_bytes);
    1542                 :            :                 } else {
    1543                 :          0 :                         rss_copy->key = NULL;
    1544                 :            :                 }
    1545                 :          0 :                 return rss_copy;
    1546                 :            :         }
    1547                 :            : 
    1548                 :            :         {
    1549                 :            :                 int conf_size = cnxk_flow_action_conf_size(act->type);
    1550                 :            :                 void *copy;
    1551                 :            : 
    1552         [ #  # ]:          0 :                 if (conf_size <= 0)
    1553                 :            :                         return NULL;
    1554                 :          0 :                 copy = plt_zmalloc(conf_size, 0);
    1555         [ #  # ]:          0 :                 if (copy != NULL)
    1556                 :          0 :                         memcpy(copy, act->conf, conf_size);
    1557                 :            :                 return copy;
    1558                 :            :         }
    1559                 :            : }
    1560                 :            : 
    1561                 :            : /* Map a supported rte_flow action type to its roc_npc action type, to mirror
    1562                 :            :  * the actions template into the roc engine for lifecycle/refcount ownership.
    1563                 :            :  */
    1564                 :            : static int
    1565                 :          0 : cnxk_flow_roc_action_type(enum rte_flow_action_type type, enum roc_npc_action_type *roc_type)
    1566                 :            : {
    1567   [ #  #  #  #  :          0 :         switch (type) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1568                 :          0 :         case RTE_FLOW_ACTION_TYPE_VOID:
    1569                 :            :         case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
    1570                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VOID;
    1571                 :          0 :                 return 0;
    1572                 :          0 :         case RTE_FLOW_ACTION_TYPE_DROP:
    1573                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_DROP;
    1574                 :          0 :                 return 0;
    1575                 :          0 :         case RTE_FLOW_ACTION_TYPE_PF:
    1576                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_PF;
    1577                 :          0 :                 return 0;
    1578                 :          0 :         case RTE_FLOW_ACTION_TYPE_VF:
    1579                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VF;
    1580                 :          0 :                 return 0;
    1581                 :          0 :         case RTE_FLOW_ACTION_TYPE_FLAG:
    1582                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_FLAG;
    1583                 :          0 :                 return 0;
    1584                 :          0 :         case RTE_FLOW_ACTION_TYPE_MARK:
    1585                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_MARK;
    1586                 :          0 :                 return 0;
    1587                 :          0 :         case RTE_FLOW_ACTION_TYPE_COUNT:
    1588                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_COUNT;
    1589                 :          0 :                 return 0;
    1590                 :          0 :         case RTE_FLOW_ACTION_TYPE_QUEUE:
    1591                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_QUEUE;
    1592                 :          0 :                 return 0;
    1593                 :          0 :         case RTE_FLOW_ACTION_TYPE_RSS:
    1594                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_RSS;
    1595                 :          0 :                 return 0;
    1596                 :          0 :         case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
    1597                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
    1598                 :          0 :                 return 0;
    1599                 :          0 :         case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
    1600                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
    1601                 :          0 :                 return 0;
    1602                 :          0 :         case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
    1603                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
    1604                 :          0 :                 return 0;
    1605                 :          0 :         case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
    1606                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
    1607                 :          0 :                 return 0;
    1608                 :          0 :         case RTE_FLOW_ACTION_TYPE_AGE:
    1609                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_AGE;
    1610                 :          0 :                 return 0;
    1611                 :          0 :         case RTE_FLOW_ACTION_TYPE_PORT_ID:
    1612                 :            :         case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
    1613                 :            :         case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
    1614                 :          0 :                 *roc_type = ROC_NPC_ACTION_TYPE_PORT_ID;
    1615                 :          0 :                 return 0;
    1616                 :            :         default:
    1617                 :            :                 return -1;
    1618                 :            :         }
    1619                 :            : }
    1620                 :            : 
    1621                 :            : struct rte_flow_actions_template *
    1622         [ #  # ]:          0 : cnxk_flow_actions_template_create(struct rte_eth_dev *eth_dev,
    1623                 :            :                                   const struct rte_flow_actions_template_attr *attr,
    1624                 :            :                                   const struct rte_flow_action actions[],
    1625                 :            :                                   const struct rte_flow_action masks[],
    1626                 :            :                                   struct rte_flow_error *error)
    1627                 :            : {
    1628                 :            :         const char *errmsg = "Failed to allocate actions template";
    1629                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1630                 :            :         struct cnxk_flow_actions_template *tmpl = NULL;
    1631                 :            :         struct roc_npc_actions_template_attr roc_attr;
    1632                 :            :         struct roc_npc_action *roc_actions = NULL;
    1633                 :            :         int i, nb_actions = 0, errcode = ENOMEM;
    1634                 :          0 :         struct roc_npc *npc = &dev->npc;
    1635                 :          0 :         int roc_err = 0;
    1636                 :            : 
    1637         [ #  # ]:          0 :         if (attr == NULL) {
    1638                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1639                 :            :                                    "NULL template attr");
    1640                 :          0 :                 return NULL;
    1641                 :            :         }
    1642                 :            : 
    1643         [ #  # ]:          0 :         if (actions == NULL) {
    1644                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1645                 :            :                                    "NULL actions");
    1646                 :          0 :                 return NULL;
    1647                 :            :         }
    1648                 :            : 
    1649         [ #  # ]:          0 :         while (actions[nb_actions].type != RTE_FLOW_ACTION_TYPE_END)
    1650                 :          0 :                 nb_actions++;
    1651                 :            : 
    1652                 :            :         /* Reject oversized templates; rules are built into fixed-size stack
    1653                 :            :          * arrays (combined_actions[ROC_NPC_MAX_ACTION_COUNT] plus END).
    1654                 :            :          */
    1655         [ #  # ]:          0 :         if (nb_actions > ROC_NPC_MAX_ACTION_COUNT - 1) {
    1656                 :            :                 errcode = ENOTSUP;
    1657                 :            :                 errmsg = "too many actions for hardware";
    1658                 :          0 :                 goto err;
    1659                 :            :         }
    1660                 :            : 
    1661                 :          0 :         tmpl = plt_zmalloc(sizeof(*tmpl), 0);
    1662         [ #  # ]:          0 :         if (tmpl == NULL)
    1663                 :          0 :                 goto err;
    1664                 :            : 
    1665                 :          0 :         tmpl->attr = *attr;
    1666                 :          0 :         tmpl->nb_actions = nb_actions;
    1667                 :            : 
    1668                 :          0 :         tmpl->actions = plt_zmalloc((nb_actions + 1) * sizeof(struct rte_flow_action), 0);
    1669         [ #  # ]:          0 :         if (tmpl->actions == NULL)
    1670                 :          0 :                 goto err;
    1671                 :            : 
    1672                 :          0 :         tmpl->masks = plt_zmalloc((nb_actions + 1) * sizeof(struct rte_flow_action), 0);
    1673         [ #  # ]:          0 :         if (tmpl->masks == NULL)
    1674                 :          0 :                 goto err;
    1675                 :            : 
    1676                 :            :         /* up to 2 conf copies (action + mask) per action */
    1677                 :          0 :         tmpl->copies = plt_zmalloc(2 * (nb_actions + 1) * sizeof(void *), 0);
    1678         [ #  # ]:          0 :         if (tmpl->copies == NULL)
    1679                 :          0 :                 goto err;
    1680                 :            : 
    1681         [ #  # ]:          0 :         for (i = 0; i < nb_actions; i++) {
    1682         [ #  # ]:          0 :                 enum rte_flow_action_type t = actions[i].type;
    1683                 :            :                 int sz = cnxk_flow_action_conf_size(t);
    1684                 :            : 
    1685         [ #  # ]:          0 :                 if (sz < 0 && t != RTE_FLOW_ACTION_TYPE_RSS) {
    1686                 :            :                         errcode = ENOTSUP;
    1687                 :            :                         errmsg = "Unsupported action in template "
    1688                 :            :                                  "(supports VOID/DROP/QUEUE/PF/VF/MARK/FLAG/COUNT/RSS/"
    1689                 :            :                                  "OF_POP_VLAN/OF_PUSH_VLAN/OF_SET_VLAN_VID/"
    1690                 :            :                                  "OF_SET_VLAN_PCP/AGE/REPRESENTED_PORT/"
    1691                 :            :                                  "PORT_REPRESENTOR/PORT_ID/VXLAN_DECAP)";
    1692                 :          0 :                         goto err;
    1693                 :            :                 }
    1694                 :            : 
    1695                 :          0 :                 tmpl->actions[i].type = t;
    1696                 :            : 
    1697         [ #  # ]:          0 :                 if (t == RTE_FLOW_ACTION_TYPE_RSS) {
    1698                 :            :                         /* RSS has nested pointers — use deep-copy helper. */
    1699                 :          0 :                         void *copy = cnxk_flow_dup_action_conf(&actions[i]);
    1700                 :            : 
    1701   [ #  #  #  # ]:          0 :                         if (copy == NULL && actions[i].conf != NULL) {
    1702                 :            :                                 const struct rte_flow_action_rss *rss = actions[i].conf;
    1703                 :            : 
    1704                 :            :                                 /* Malformed conf vs allocation failure: report a
    1705                 :            :                                  * precise errno instead of the default ENOMEM.
    1706                 :            :                                  */
    1707   [ #  #  #  # ]:          0 :                                 if ((rss->queue_num && rss->queue == NULL) ||
    1708   [ #  #  #  # ]:          0 :                                     (rss->key_len && rss->key == NULL)) {
    1709                 :            :                                         errcode = EINVAL;
    1710                 :            :                                         errmsg = "Malformed RSS action conf in template";
    1711                 :            :                                 }
    1712                 :          0 :                                 goto err;
    1713                 :            :                         }
    1714                 :          0 :                         tmpl->actions[i].conf = copy;
    1715         [ #  # ]:          0 :                         if (copy)
    1716                 :          0 :                                 tmpl->copies[tmpl->nb_copies++] = copy;
    1717                 :            :                 } else {
    1718         [ #  # ]:          0 :                         if (cnxk_flow_dup_conf(tmpl->copies, &tmpl->nb_copies, actions[i].conf, sz,
    1719                 :            :                                                &tmpl->actions[i].conf))
    1720                 :          0 :                                 goto err;
    1721                 :            :                 }
    1722                 :            : 
    1723         [ #  # ]:          0 :                 if (masks != NULL) {
    1724         [ #  # ]:          0 :                         if (masks[i].type != t) {
    1725                 :            :                                 errcode = EINVAL;
    1726                 :            :                                 errmsg = "actions/masks type mismatch in template";
    1727                 :          0 :                                 goto err;
    1728                 :            :                         }
    1729                 :          0 :                         tmpl->masks[i].type = t;
    1730         [ #  # ]:          0 :                         if (t == RTE_FLOW_ACTION_TYPE_RSS) {
    1731                 :            :                                 /* RSS nests pointers and cannot be copied by the flat
    1732                 :            :                                  * helper; reject a non-NULL RSS mask.
    1733                 :            :                                  */
    1734         [ #  # ]:          0 :                                 if (masks[i].conf != NULL) {
    1735                 :            :                                         errcode = ENOTSUP;
    1736                 :            :                                         errmsg = "Non-NULL RSS mask conf is not "
    1737                 :            :                                                  "supported in template";
    1738                 :          0 :                                         goto err;
    1739                 :            :                                 }
    1740                 :          0 :                                 tmpl->masks[i].conf = NULL;
    1741         [ #  # ]:          0 :                         } else if (cnxk_flow_dup_conf(tmpl->copies, &tmpl->nb_copies, masks[i].conf,
    1742                 :          0 :                                                       sz > 0 ? sz : 0, &tmpl->masks[i].conf)) {
    1743                 :          0 :                                 goto err;
    1744                 :            :                         }
    1745                 :            :                 }
    1746                 :            :         }
    1747                 :            : 
    1748                 :          0 :         tmpl->actions[nb_actions].type = RTE_FLOW_ACTION_TYPE_END;
    1749                 :          0 :         tmpl->masks[nb_actions].type = RTE_FLOW_ACTION_TYPE_END;
    1750                 :          0 :         tmpl->roc_tmpl = NULL;
    1751                 :          0 :         tmpl->refcnt = 0;
    1752                 :            : 
    1753                 :            :         /* Mirror only action types into the roc engine for template lifecycle
    1754                 :            :          * and refcount ownership; per-rule conf translation stays in cnxk.
    1755                 :            :          */
    1756                 :          0 :         roc_actions = plt_zmalloc((nb_actions + 1) * sizeof(*roc_actions), 0);
    1757         [ #  # ]:          0 :         if (roc_actions == NULL)
    1758                 :          0 :                 goto err;
    1759                 :            : 
    1760         [ #  # ]:          0 :         for (i = 0; i < nb_actions; i++) {
    1761                 :            :                 enum roc_npc_action_type rt;
    1762                 :            : 
    1763         [ #  # ]:          0 :                 if (cnxk_flow_roc_action_type(tmpl->actions[i].type, &rt)) {
    1764                 :            :                         errcode = ENOTSUP;
    1765                 :            :                         errmsg = "Unsupported action in template";
    1766                 :          0 :                         goto err;
    1767                 :            :                 }
    1768                 :          0 :                 roc_actions[i].type = rt;
    1769                 :          0 :                 roc_actions[i].conf = NULL;
    1770                 :            :         }
    1771                 :          0 :         roc_actions[nb_actions].type = ROC_NPC_ACTION_TYPE_END;
    1772                 :            : 
    1773                 :            :         memset(&roc_attr, 0, sizeof(roc_attr));
    1774                 :          0 :         roc_attr.ingress = attr->ingress;
    1775                 :          0 :         roc_attr.egress = attr->egress;
    1776                 :          0 :         roc_attr.transfer = attr->transfer;
    1777                 :            : 
    1778                 :          0 :         tmpl->roc_tmpl =
    1779                 :          0 :                 roc_npc_actions_template_create(npc, &roc_attr, roc_actions, NULL, &roc_err);
    1780                 :          0 :         plt_free(roc_actions);
    1781                 :            :         roc_actions = NULL;
    1782         [ #  # ]:          0 :         if (tmpl->roc_tmpl == NULL) {
    1783         [ #  # ]:          0 :                 errcode = (roc_err < 0) ? -roc_err : ENOMEM;
    1784                 :            :                 errmsg = "Failed to create ROC actions template";
    1785                 :          0 :                 goto err;
    1786                 :            :         }
    1787                 :            : 
    1788                 :            :         return (struct rte_flow_actions_template *)tmpl;
    1789                 :            : 
    1790                 :          0 : err:
    1791                 :          0 :         plt_free(roc_actions);
    1792         [ #  # ]:          0 :         if (tmpl != NULL) {
    1793                 :            :                 uint16_t j;
    1794         [ #  # ]:          0 :                 if (tmpl->roc_tmpl != NULL)
    1795                 :          0 :                         roc_npc_actions_template_destroy(npc, tmpl->roc_tmpl);
    1796         [ #  # ]:          0 :                 for (j = 0; j < tmpl->nb_copies; j++)
    1797                 :          0 :                         plt_free(tmpl->copies[j]);
    1798                 :          0 :                 plt_free(tmpl->copies);
    1799                 :          0 :                 plt_free(tmpl->masks);
    1800                 :          0 :                 plt_free(tmpl->actions);
    1801                 :          0 :                 plt_free(tmpl);
    1802                 :            :         }
    1803                 :          0 :         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, errmsg);
    1804                 :          0 :         return NULL;
    1805                 :            : }
    1806                 :            : 
    1807                 :            : int
    1808         [ #  # ]:          0 : cnxk_flow_actions_template_destroy(struct rte_eth_dev *eth_dev,
    1809                 :            :                                    struct rte_flow_actions_template *templ,
    1810                 :            :                                    struct rte_flow_error *error)
    1811                 :            : {
    1812                 :            :         struct cnxk_flow_actions_template *tmpl = (struct cnxk_flow_actions_template *)templ;
    1813                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1814                 :          0 :         struct roc_npc *npc = &dev->npc;
    1815                 :            :         uint16_t i;
    1816                 :            :         int rc;
    1817                 :            : 
    1818         [ #  # ]:          0 :         if (tmpl == NULL)
    1819                 :            :                 return 0;
    1820                 :            : 
    1821         [ #  # ]:          0 :         if (tmpl->refcnt != 0)
    1822                 :          0 :                 return rte_flow_error_set(error, EBUSY, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1823                 :            :                                           "actions template still in use by a table");
    1824                 :            : 
    1825                 :          0 :         rc = roc_npc_actions_template_destroy(npc, tmpl->roc_tmpl);
    1826         [ #  # ]:          0 :         if (rc)
    1827                 :          0 :                 return rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1828                 :            :                                           "failed to destroy ROC actions template");
    1829                 :            : 
    1830         [ #  # ]:          0 :         for (i = 0; i < tmpl->nb_copies; i++)
    1831                 :          0 :                 plt_free(tmpl->copies[i]);
    1832                 :          0 :         plt_free(tmpl->copies);
    1833                 :          0 :         plt_free(tmpl->masks);
    1834                 :          0 :         plt_free(tmpl->actions);
    1835                 :          0 :         plt_free(tmpl);
    1836                 :          0 :         return 0;
    1837                 :            : }
    1838                 :            : 
    1839                 :            : struct rte_flow_template_table *
    1840         [ #  # ]:          0 : cnxk_flow_template_table_create(struct rte_eth_dev *eth_dev,
    1841                 :            :                                 const struct rte_flow_template_table_attr *table_attr,
    1842                 :            :                                 struct rte_flow_pattern_template *pattern_templates[],
    1843                 :            :                                 uint8_t nb_pattern_templates,
    1844                 :            :                                 struct rte_flow_actions_template *actions_templates[],
    1845                 :            :                                 uint8_t nb_actions_templates, struct rte_flow_error *error)
    1846                 :            : {
    1847                 :            :         struct roc_npc_pattern_template **roc_pattern_templates = NULL;
    1848                 :            :         struct roc_npc_actions_template **roc_actions_templates = NULL;
    1849                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1850                 :            :         struct roc_npc_template_table_attr roc_attr;
    1851                 :            :         enum rte_flow_table_insertion_type itype;
    1852                 :            :         const struct rte_flow_attr *fattr;
    1853                 :          0 :         struct roc_npc *npc = &dev->npc;
    1854                 :            :         struct cnxk_flow_table *table;
    1855                 :            :         uint32_t nb_flows;
    1856                 :          0 :         int errcode = 0;
    1857                 :            :         uint8_t i;
    1858                 :            : 
    1859         [ #  # ]:          0 :         if (table_attr == NULL) {
    1860                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1861                 :            :                                    "NULL table_attr");
    1862                 :          0 :                 return NULL;
    1863                 :            :         }
    1864                 :            : 
    1865                 :          0 :         itype = table_attr->insertion_type;
    1866                 :            :         fattr = &table_attr->flow_attr;
    1867                 :          0 :         nb_flows = table_attr->nb_flows;
    1868                 :            : 
    1869         [ #  # ]:          0 :         if (itype == RTE_FLOW_TABLE_INSERTION_TYPE_INDEX) {
    1870                 :          0 :                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1871                 :            :                                    "pure-index insertion not supported; NPC is match-based");
    1872                 :          0 :                 return NULL;
    1873                 :            :         }
    1874                 :            : 
    1875                 :            :         /* Validate the template handles before allocating anything. */
    1876         [ #  # ]:          0 :         for (i = 0; i < nb_pattern_templates; i++) {
    1877         [ #  # ]:          0 :                 if (pattern_templates[i] == NULL) {
    1878                 :          0 :                         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1879                 :            :                                            "invalid template handle");
    1880                 :          0 :                         return NULL;
    1881                 :            :                 }
    1882                 :            :         }
    1883         [ #  # ]:          0 :         for (i = 0; i < nb_actions_templates; i++) {
    1884         [ #  # ]:          0 :                 if (actions_templates[i] == NULL) {
    1885                 :          0 :                         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1886                 :            :                                            "invalid template handle");
    1887                 :          0 :                         return NULL;
    1888                 :            :                 }
    1889                 :            :         }
    1890                 :            : 
    1891                 :          0 :         table = plt_zmalloc(sizeof(*table), 0);
    1892         [ #  # ]:          0 :         if (table == NULL)
    1893                 :          0 :                 goto enomem;
    1894                 :            : 
    1895                 :          0 :         table->insertion_type = itype;
    1896                 :          0 :         table->nb_flows = nb_flows;
    1897                 :            : 
    1898         [ #  # ]:          0 :         memset(&table->flow_attr, 0, sizeof(table->flow_attr));
    1899                 :          0 :         table->flow_attr.priority = fattr->priority;
    1900                 :          0 :         table->flow_attr.ingress = fattr->ingress;
    1901                 :          0 :         table->flow_attr.egress = fattr->egress;
    1902                 :          0 :         table->transfer = fattr->transfer;
    1903                 :            : 
    1904         [ #  # ]:          0 :         if (nb_pattern_templates != 0) {
    1905                 :          0 :                 table->pattern_templates =
    1906                 :          0 :                         plt_zmalloc(nb_pattern_templates * sizeof(*table->pattern_templates), 0);
    1907         [ #  # ]:          0 :                 if (table->pattern_templates == NULL)
    1908                 :          0 :                         goto free_table;
    1909                 :            :                 roc_pattern_templates =
    1910                 :          0 :                         plt_zmalloc(nb_pattern_templates * sizeof(*roc_pattern_templates), 0);
    1911         [ #  # ]:          0 :                 if (roc_pattern_templates == NULL)
    1912                 :          0 :                         goto free_table;
    1913                 :            :         }
    1914         [ #  # ]:          0 :         if (nb_actions_templates != 0) {
    1915                 :          0 :                 table->actions_templates =
    1916                 :          0 :                         plt_zmalloc(nb_actions_templates * sizeof(*table->actions_templates), 0);
    1917         [ #  # ]:          0 :                 if (table->actions_templates == NULL)
    1918                 :          0 :                         goto free_table;
    1919                 :            :                 roc_actions_templates =
    1920                 :          0 :                         plt_zmalloc(nb_actions_templates * sizeof(*roc_actions_templates), 0);
    1921         [ #  # ]:          0 :                 if (roc_actions_templates == NULL)
    1922                 :          0 :                         goto free_table;
    1923                 :            :         }
    1924                 :            : 
    1925                 :            :         /* Hand the table to the roc engine, which owns rule storage, MCAM
    1926                 :            :          * reservation and the rule lifecycle; cnxk keeps per-rule translation.
    1927                 :            :          */
    1928                 :            :         memset(&roc_attr, 0, sizeof(roc_attr));
    1929                 :          0 :         roc_attr.flow_attr = table->flow_attr;
    1930                 :          0 :         roc_attr.transfer = table->transfer;
    1931                 :          0 :         roc_attr.nb_flows = nb_flows;
    1932                 :          0 :         roc_attr.insertion_type = (itype == RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN) ?
    1933                 :          0 :                                           ROC_NPC_TEMPLATE_INSERTION_INDEX_WITH_PATTERN :
    1934                 :            :                                           ROC_NPC_TEMPLATE_INSERTION_PATTERN;
    1935                 :            :         /* Stash this wrapper as the table cookie so async_actions_update can
    1936                 :            :          * recover the rte templates from just the flow handle.
    1937                 :            :          */
    1938                 :          0 :         roc_attr.cookie = table;
    1939                 :            : 
    1940         [ #  # ]:          0 :         for (i = 0; i < nb_pattern_templates; i++) {
    1941                 :          0 :                 table->pattern_templates[i] =
    1942                 :          0 :                         (struct cnxk_flow_pattern_template *)pattern_templates[i];
    1943                 :          0 :                 roc_pattern_templates[i] = table->pattern_templates[i]->roc_tmpl;
    1944         [ #  # ]:          0 :                 if (roc_pattern_templates[i] == NULL)
    1945                 :          0 :                         goto bad_handle;
    1946                 :            :         }
    1947         [ #  # ]:          0 :         for (i = 0; i < nb_actions_templates; i++) {
    1948                 :          0 :                 table->actions_templates[i] =
    1949                 :          0 :                         (struct cnxk_flow_actions_template *)actions_templates[i];
    1950                 :          0 :                 roc_actions_templates[i] = table->actions_templates[i]->roc_tmpl;
    1951         [ #  # ]:          0 :                 if (roc_actions_templates[i] == NULL)
    1952                 :          0 :                         goto bad_handle;
    1953                 :            :         }
    1954                 :            : 
    1955                 :            :         /* clang-format off */
    1956                 :          0 :         table->roc_table = roc_npc_template_table_create(npc, &roc_attr,
    1957                 :            :                         roc_pattern_templates, nb_pattern_templates,
    1958                 :            :                         roc_actions_templates, nb_actions_templates, &errcode);
    1959                 :            :         /* clang-format on */
    1960                 :          0 :         plt_free(roc_pattern_templates);
    1961                 :          0 :         plt_free(roc_actions_templates);
    1962                 :            :         roc_pattern_templates = NULL;
    1963                 :            :         roc_actions_templates = NULL;
    1964         [ #  # ]:          0 :         if (table->roc_table == NULL) {
    1965                 :          0 :                 plt_free(table->pattern_templates);
    1966                 :          0 :                 plt_free(table->actions_templates);
    1967                 :          0 :                 plt_free(table);
    1968         [ #  # ]:          0 :                 rte_flow_error_set(error, errcode < 0 ? -errcode : ENOMEM,
    1969                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1970                 :            :                                    "could not create template table");
    1971                 :          0 :                 return NULL;
    1972                 :            :         }
    1973                 :            : 
    1974         [ #  # ]:          0 :         for (i = 0; i < nb_pattern_templates; i++)
    1975                 :          0 :                 table->pattern_templates[i]->refcnt++;
    1976                 :          0 :         table->nb_pattern_templates = nb_pattern_templates;
    1977         [ #  # ]:          0 :         for (i = 0; i < nb_actions_templates; i++)
    1978                 :          0 :                 table->actions_templates[i]->refcnt++;
    1979                 :          0 :         table->nb_actions_templates = nb_actions_templates;
    1980                 :            : 
    1981                 :          0 :         return (struct rte_flow_template_table *)table;
    1982                 :            : 
    1983                 :          0 : bad_handle:
    1984                 :          0 :         plt_free(roc_pattern_templates);
    1985                 :          0 :         plt_free(roc_actions_templates);
    1986                 :          0 :         plt_free(table->pattern_templates);
    1987                 :          0 :         plt_free(table->actions_templates);
    1988                 :          0 :         plt_free(table);
    1989                 :          0 :         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1990                 :            :                            "invalid template handle");
    1991                 :          0 :         return NULL;
    1992                 :            : 
    1993                 :          0 : free_table:
    1994                 :          0 :         plt_free(roc_pattern_templates);
    1995                 :          0 :         plt_free(roc_actions_templates);
    1996                 :          0 :         plt_free(table->pattern_templates);
    1997                 :          0 :         plt_free(table->actions_templates);
    1998                 :          0 :         plt_free(table);
    1999                 :            : 
    2000                 :          0 : enomem:
    2001                 :          0 :         rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "out of memory");
    2002                 :          0 :         return NULL;
    2003                 :            : }
    2004                 :            : 
    2005                 :            : int
    2006         [ #  # ]:          0 : cnxk_flow_template_table_destroy(struct rte_eth_dev *eth_dev,
    2007                 :            :                                  struct rte_flow_template_table *tbl_handle,
    2008                 :            :                                  struct rte_flow_error *error)
    2009                 :            : {
    2010                 :            :         struct cnxk_flow_table *table = (struct cnxk_flow_table *)tbl_handle;
    2011                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2012                 :          0 :         struct roc_npc *npc = &dev->npc;
    2013                 :            :         uint8_t i;
    2014                 :            :         int rc;
    2015                 :            : 
    2016         [ #  # ]:          0 :         if (table == NULL)
    2017                 :            :                 return 0;
    2018                 :            : 
    2019                 :            :         /* The roc engine guards teardown: a busy table returns -EBUSY and
    2020                 :            :          * nothing is freed, so the cnxk wrapper and refcounts stay intact.
    2021                 :            :          */
    2022                 :          0 :         rc = roc_npc_template_table_destroy(npc, table->roc_table);
    2023         [ #  # ]:          0 :         if (rc == -EBUSY)
    2024                 :          0 :                 return rte_flow_error_set(error, EBUSY, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2025                 :            :                                           "table still has live flows; destroy them first");
    2026         [ #  # ]:          0 :         if (rc)
    2027                 :          0 :                 return rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2028                 :            :                                           "failed to destroy template table");
    2029                 :            : 
    2030         [ #  # ]:          0 :         for (i = 0; i < table->nb_pattern_templates; i++)
    2031                 :          0 :                 table->pattern_templates[i]->refcnt--;
    2032         [ #  # ]:          0 :         for (i = 0; i < table->nb_actions_templates; i++)
    2033                 :          0 :                 table->actions_templates[i]->refcnt--;
    2034                 :            : 
    2035                 :          0 :         plt_free(table->pattern_templates);
    2036                 :          0 :         plt_free(table->actions_templates);
    2037                 :          0 :         plt_free(table);
    2038                 :          0 :         return 0;
    2039                 :            : }
    2040                 :            : 
    2041                 :            : /* Reject per-rule pattern/actions arrays whose types/order do not mirror the
    2042                 :            :  * chosen templates; the merge takes the type from the template but the
    2043                 :            :  * spec/conf from the per-rule array. A NULL array uses template defaults.
    2044                 :            :  */
    2045                 :            : static int
    2046                 :            : cnxk_flow_check_items(const struct cnxk_flow_pattern_template *pt,
    2047                 :            :                       const struct rte_flow_item items[])
    2048                 :            : {
    2049                 :            :         uint16_t k;
    2050                 :            : 
    2051                 :          0 :         if (items == NULL)
    2052                 :            :                 return 0;
    2053   [ #  #  #  # ]:          0 :         for (k = 0; k < pt->nb_items; k++)
    2054   [ #  #  #  # ]:          0 :                 if (items[k].type != pt->pattern[k].type)
    2055                 :            :                         return -EINVAL;
    2056   [ #  #  #  # ]:          0 :         if (items[pt->nb_items].type != RTE_FLOW_ITEM_TYPE_END)
    2057                 :            :                 return -EINVAL;
    2058                 :            :         return 0;
    2059                 :            : }
    2060                 :            : 
    2061                 :            : static int
    2062                 :            : cnxk_flow_check_actions(const struct cnxk_flow_actions_template *at,
    2063                 :            :                         const struct rte_flow_action actions[])
    2064                 :            : {
    2065                 :            :         uint16_t k;
    2066                 :            : 
    2067   [ #  #  #  # ]:          0 :         if (actions == NULL)
    2068                 :            :                 return 0;
    2069   [ #  #  #  #  :          0 :         for (k = 0; k < at->nb_actions; k++)
                   #  # ]
    2070   [ #  #  #  #  :          0 :                 if (actions[k].type != at->actions[k].type)
                   #  # ]
    2071                 :            :                         return -EINVAL;
    2072   [ #  #  #  #  :          0 :         if (actions[at->nb_actions].type != RTE_FLOW_ACTION_TYPE_END)
                   #  # ]
    2073                 :            :                 return -EINVAL;
    2074                 :            :         return 0;
    2075                 :            : }
    2076                 :            : 
    2077                 :            : /* Enqueue a PATTERN create: merge the per-rule spec with the templates,
    2078                 :            :  * translate to roc_npc types, and hand to the roc engine (programmed at push).
    2079                 :            :  */
    2080                 :            : struct rte_flow *
    2081         [ #  # ]:          0 : cnxk_flow_async_create(struct rte_eth_dev *eth_dev, uint32_t queue,
    2082                 :            :                        const struct rte_flow_op_attr *attr,
    2083                 :            :                        struct rte_flow_template_table *tbl_handle,
    2084                 :            :                        const struct rte_flow_item items[], uint8_t pattern_template_index,
    2085                 :            :                        const struct rte_flow_action actions[], uint8_t action_template_index,
    2086                 :            :                        void *user_data, struct rte_flow_error *error)
    2087                 :            : {
    2088                 :            :         struct cnxk_flow_table *table = (struct cnxk_flow_table *)tbl_handle;
    2089                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2090                 :            :         struct cnxk_flow_pattern_template *pt;
    2091                 :            :         struct cnxk_flow_actions_template *at;
    2092                 :            :         struct roc_npc_template_flow *flow;
    2093                 :          0 :         struct roc_npc *npc = &dev->npc;
    2094                 :            : 
    2095                 :          0 :         uint64_t free_allocs[ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2096                 :          0 :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2097                 :            :         struct rte_flow_action combined_actions[ROC_NPC_MAX_ACTION_COUNT];
    2098                 :          0 :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT] = {0};
    2099                 :            :         struct rte_flow_item combined_items[ROC_NPC_ITEM_TYPE_END + 1];
    2100                 :          0 :         struct roc_npc_action_sample in_sample = {0};
    2101                 :            :         struct rte_flow_attr rte_attr;
    2102                 :            :         struct roc_npc_attr in_attr;
    2103                 :          0 :         uint16_t dst_pf_func = 0;
    2104                 :          0 :         uint64_t def_action = 0;
    2105                 :          0 :         int errcode = 0;
    2106                 :            :         uint16_t k;
    2107                 :            :         int rc, j;
    2108                 :            : 
    2109                 :            :         RTE_SET_USED(attr);
    2110                 :            : 
    2111         [ #  # ]:          0 :         if (table == NULL) {
    2112                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2113                 :            :                                    "bad table");
    2114                 :          0 :                 return NULL;
    2115                 :            :         }
    2116         [ #  # ]:          0 :         if (table->insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN) {
    2117                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2118                 :            :                                    "table is index-insertion; use create_by_index_with_pattern");
    2119                 :          0 :                 return NULL;
    2120                 :            :         }
    2121         [ #  # ]:          0 :         if (pattern_template_index >= table->nb_pattern_templates ||
    2122         [ #  # ]:          0 :             action_template_index >= table->nb_actions_templates) {
    2123                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2124                 :            :                                    "template index out of range");
    2125                 :          0 :                 return NULL;
    2126                 :            :         }
    2127                 :            : 
    2128                 :          0 :         pt = table->pattern_templates[pattern_template_index];
    2129         [ #  # ]:          0 :         at = table->actions_templates[action_template_index];
    2130                 :            : 
    2131                 :            :         if (cnxk_flow_check_items(pt, items) != 0 || cnxk_flow_check_actions(at, actions) != 0) {
    2132                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2133                 :            :                                    "pattern/actions do not match the selected templates");
    2134                 :          0 :                 return NULL;
    2135                 :            :         }
    2136                 :            : 
    2137                 :            :         /* Merge: spec comes from the per-rule call, last/mask from the template. */
    2138         [ #  # ]:          0 :         for (k = 0; k < pt->nb_items; k++) {
    2139                 :          0 :                 combined_items[k].type = pt->pattern[k].type;
    2140         [ #  # ]:          0 :                 combined_items[k].spec = items ? items[k].spec : NULL;
    2141                 :          0 :                 combined_items[k].last = pt->pattern[k].last;
    2142                 :          0 :                 combined_items[k].mask = pt->pattern[k].mask;
    2143                 :            :         }
    2144                 :          0 :         combined_items[pt->nb_items].type = RTE_FLOW_ITEM_TYPE_END;
    2145                 :            : 
    2146                 :            :         /* Merge: per-rule conf overrides the template conf. */
    2147         [ #  # ]:          0 :         for (k = 0; k < at->nb_actions; k++) {
    2148                 :          0 :                 combined_actions[k].type = at->actions[k].type;
    2149                 :          0 :                 combined_actions[k].conf =
    2150   [ #  #  #  # ]:          0 :                         (actions && actions[k].conf) ? actions[k].conf : at->actions[k].conf;
    2151                 :            :         }
    2152                 :          0 :         combined_actions[at->nb_actions].type = RTE_FLOW_ACTION_TYPE_END;
    2153                 :            : 
    2154                 :            :         memset(&rte_attr, 0, sizeof(rte_attr));
    2155                 :          0 :         rte_attr.priority = table->flow_attr.priority;
    2156                 :          0 :         rte_attr.ingress = table->flow_attr.ingress;
    2157                 :          0 :         rte_attr.egress = table->flow_attr.egress;
    2158                 :          0 :         rte_attr.transfer = table->transfer;
    2159                 :            : 
    2160                 :            :         /* Translate into roc_npc types. The RSS flow key is stashed in
    2161                 :            :          * npc->flowkey_cfg_state so the engine can restore it at push().
    2162                 :            :          */
    2163                 :            :         memset(&in_attr, 0, sizeof(in_attr));
    2164                 :          0 :         rc = cnxk_map_flow_data(eth_dev, &rte_attr, combined_items, combined_actions, &in_attr,
    2165                 :            :                                 in_pattern, in_actions, &in_sample, &npc->flowkey_cfg_state,
    2166                 :            :                                 &dst_pf_func, &def_action, false, free_allocs, 0);
    2167         [ #  # ]:          0 :         if (rc == 0)
    2168                 :          0 :                 flow = roc_npc_async_flow_create(npc, queue, table->roc_table, in_pattern,
    2169                 :            :                                                  in_actions, dst_pf_func, def_action, user_data,
    2170                 :            :                                                  &errcode);
    2171                 :            :         else
    2172                 :            :                 flow = NULL;
    2173                 :            : 
    2174   [ #  #  #  # ]:          0 :         for (j = 0; j < (int)RTE_DIM(free_allocs) && free_allocs[j]; j++)
    2175                 :          0 :                 plt_free((void *)free_allocs[j]);
    2176                 :            : 
    2177         [ #  # ]:          0 :         if (rc != 0) {
    2178                 :          0 :                 rte_flow_error_set(error, rc < 0 ? -rc : rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
    2179                 :            :                                    "Failed to map flow data");
    2180                 :          0 :                 return NULL;
    2181                 :            :         }
    2182         [ #  # ]:          0 :         if (flow == NULL) {
    2183         [ #  # ]:          0 :                 rte_flow_error_set(error, errcode < 0 ? -errcode : EINVAL,
    2184                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2185                 :            :                                    "async flow create failed");
    2186                 :          0 :                 return NULL;
    2187                 :            :         }
    2188                 :            : 
    2189                 :            :         return (struct rte_flow *)flow;
    2190                 :            : }
    2191                 :            : 
    2192                 :            : /* Enqueue a destroy operation. */
    2193                 :            : int
    2194                 :          0 : cnxk_flow_async_destroy(struct rte_eth_dev *eth_dev, uint32_t queue,
    2195                 :            :                         const struct rte_flow_op_attr *attr, struct rte_flow *flow, void *user_data,
    2196                 :            :                         struct rte_flow_error *error)
    2197                 :            : {
    2198                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2199                 :          0 :         struct roc_npc *npc = &dev->npc;
    2200                 :            :         int rc;
    2201                 :            : 
    2202                 :            :         RTE_SET_USED(attr);
    2203                 :            : 
    2204                 :          0 :         rc = roc_npc_async_flow_destroy(npc, queue, (struct roc_npc_template_flow *)flow,
    2205                 :            :                                         user_data);
    2206         [ #  # ]:          0 :         if (rc)
    2207                 :          0 :                 return rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    2208                 :            :                                           "bad queue or flow handle");
    2209                 :            :         return 0;
    2210                 :            : }
    2211                 :            : 
    2212                 :            : /* Flush all pending async operations to hardware in one batch. */
    2213                 :            : int
    2214                 :          0 : cnxk_flow_push(struct rte_eth_dev *eth_dev, uint32_t queue, struct rte_flow_error *error)
    2215                 :            : {
    2216                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2217                 :          0 :         struct roc_npc *npc = &dev->npc;
    2218                 :            :         int rc;
    2219                 :            : 
    2220                 :          0 :         rc = roc_npc_flow_push(npc, queue);
    2221         [ #  # ]:          0 :         if (rc)
    2222                 :          0 :                 return rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2223                 :            :                                           "bad queue");
    2224                 :            :         return 0;
    2225                 :            : }
    2226                 :            : 
    2227                 :            : /* Return results for completed ops back to the application. */
    2228                 :            : int
    2229                 :          0 : cnxk_flow_pull(struct rte_eth_dev *eth_dev, uint32_t queue, struct rte_flow_op_result res[],
    2230                 :            :                uint16_t n_res, struct rte_flow_error *error)
    2231                 :            : {
    2232                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2233                 :          0 :         struct roc_npc *npc = &dev->npc;
    2234                 :            :         uint16_t done = 0;
    2235                 :            : 
    2236                 :            :         /* Drain roc engine results in fixed-size batches, translating each
    2237                 :            :          * roc op result into the rte op result without a per-pull allocation.
    2238                 :            :          */
    2239         [ #  # ]:          0 :         while (done < n_res) {
    2240                 :            :                 struct roc_npc_flow_op_result rres[64];
    2241                 :          0 :                 uint16_t batch = RTE_MIN((uint16_t)(n_res - done), (uint16_t)RTE_DIM(rres));
    2242                 :          0 :                 int got = roc_npc_flow_pull(npc, queue, rres, batch);
    2243                 :            :                 uint16_t k;
    2244                 :            : 
    2245         [ #  # ]:          0 :                 if (got < 0) {
    2246         [ #  # ]:          0 :                         if (done != 0)
    2247                 :            :                                 break;
    2248                 :          0 :                         return rte_flow_error_set(error, -got, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
    2249                 :            :                                                   NULL, "bad queue");
    2250                 :            :                 }
    2251                 :            : 
    2252         [ #  # ]:          0 :                 for (k = 0; k < (uint16_t)got; k++) {
    2253                 :          0 :                         res[done + k].status =
    2254                 :          0 :                                 (rres[k].rc == 0) ? RTE_FLOW_OP_SUCCESS : RTE_FLOW_OP_ERROR;
    2255                 :          0 :                         res[done + k].user_data = rres[k].user_data;
    2256                 :            :                 }
    2257                 :          0 :                 done += (uint16_t)got;
    2258                 :            : 
    2259         [ #  # ]:          0 :                 if (got < batch)
    2260                 :            :                         break;
    2261                 :            :         }
    2262                 :            : 
    2263                 :          0 :         return done;
    2264                 :            : }
    2265                 :            : 
    2266                 :            : struct rte_flow *
    2267                 :          0 : cnxk_flow_async_create_by_index(struct rte_eth_dev *eth_dev, uint32_t queue,
    2268                 :            :                                 const struct rte_flow_op_attr *attr,
    2269                 :            :                                 struct rte_flow_template_table *table, uint32_t rule_index,
    2270                 :            :                                 const struct rte_flow_action actions[],
    2271                 :            :                                 uint8_t action_template_index, void *user_data,
    2272                 :            :                                 struct rte_flow_error *error)
    2273                 :            : {
    2274                 :            :         RTE_SET_USED(eth_dev);
    2275                 :            :         RTE_SET_USED(queue);
    2276                 :            :         RTE_SET_USED(attr);
    2277                 :            :         RTE_SET_USED(table);
    2278                 :            :         RTE_SET_USED(rule_index);
    2279                 :            :         RTE_SET_USED(actions);
    2280                 :            :         RTE_SET_USED(action_template_index);
    2281                 :            :         RTE_SET_USED(user_data);
    2282                 :            : 
    2283                 :          0 :         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2284                 :            :                            "index-only insertion needs a match key; NPC is match-based");
    2285                 :          0 :         return NULL;
    2286                 :            : }
    2287                 :            : 
    2288                 :            : /* Like async_create but with an app-specified index; the app must avoid
    2289                 :            :  * concurrent creates to the same index and use a valid table index.
    2290                 :            :  */
    2291                 :            : struct rte_flow *
    2292                 :            : /* clang-format off */
    2293         [ #  # ]:          0 : cnxk_flow_async_create_by_index_with_pattern(struct rte_eth_dev *eth_dev,
    2294                 :            :                 uint32_t queue, const struct rte_flow_op_attr *attr,
    2295                 :            :                 struct rte_flow_template_table *tbl_handle, uint32_t rule_index,
    2296                 :            :                 const struct rte_flow_item items[], uint8_t pattern_template_index,
    2297                 :            :                 const struct rte_flow_action actions[],
    2298                 :            :                 uint8_t action_template_index, void *user_data,
    2299                 :            :                 struct rte_flow_error *error)
    2300                 :            : /* clang-format on */
    2301                 :            : {
    2302                 :            :         struct cnxk_flow_table *table = (struct cnxk_flow_table *)tbl_handle;
    2303                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2304                 :            :         struct cnxk_flow_pattern_template *pt;
    2305                 :            :         struct cnxk_flow_actions_template *at;
    2306                 :            :         struct roc_npc_template_flow *flow;
    2307                 :          0 :         struct roc_npc *npc = &dev->npc;
    2308                 :            : 
    2309                 :          0 :         uint64_t free_allocs[ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2310                 :          0 :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2311                 :            :         struct rte_flow_action combined_actions[ROC_NPC_MAX_ACTION_COUNT];
    2312                 :          0 :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT] = {0};
    2313                 :            :         struct rte_flow_item combined_items[ROC_NPC_ITEM_TYPE_END + 1];
    2314                 :          0 :         struct roc_npc_action_sample in_sample = {0};
    2315                 :            :         struct rte_flow_attr rte_attr;
    2316                 :            :         struct roc_npc_attr in_attr;
    2317                 :          0 :         uint32_t flowkey_cfg = 0;
    2318                 :          0 :         uint16_t dst_pf_func = 0;
    2319                 :          0 :         uint64_t def_action = 0;
    2320                 :          0 :         int errcode = 0;
    2321                 :            :         uint16_t k;
    2322                 :            :         int rc, j;
    2323                 :            : 
    2324                 :            :         RTE_SET_USED(attr);
    2325                 :            : 
    2326         [ #  # ]:          0 :         if (table == NULL) {
    2327                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2328                 :            :                                    "bad table");
    2329                 :          0 :                 return NULL;
    2330                 :            :         }
    2331         [ #  # ]:          0 :         if (table->insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN) {
    2332                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2333                 :            :                                    "table is not index-with-pattern insertion");
    2334                 :          0 :                 return NULL;
    2335                 :            :         }
    2336         [ #  # ]:          0 :         if (pattern_template_index >= table->nb_pattern_templates ||
    2337         [ #  # ]:          0 :             action_template_index >= table->nb_actions_templates) {
    2338                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2339                 :            :                                    "template index out of range");
    2340                 :          0 :                 return NULL;
    2341                 :            :         }
    2342         [ #  # ]:          0 :         if (rule_index >= table->nb_flows) {
    2343                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2344                 :            :                                    "rule_index out of range");
    2345                 :          0 :                 return NULL;
    2346                 :            :         }
    2347                 :            : 
    2348                 :          0 :         pt = table->pattern_templates[pattern_template_index];
    2349         [ #  # ]:          0 :         at = table->actions_templates[action_template_index];
    2350                 :            : 
    2351                 :            :         if (cnxk_flow_check_items(pt, items) != 0 || cnxk_flow_check_actions(at, actions) != 0) {
    2352                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2353                 :            :                                    "pattern/actions do not match the selected templates");
    2354                 :          0 :                 return NULL;
    2355                 :            :         }
    2356                 :            : 
    2357         [ #  # ]:          0 :         for (k = 0; k < pt->nb_items; k++) {
    2358                 :          0 :                 combined_items[k].type = pt->pattern[k].type;
    2359         [ #  # ]:          0 :                 combined_items[k].spec = items ? items[k].spec : NULL;
    2360                 :          0 :                 combined_items[k].last = pt->pattern[k].last;
    2361                 :          0 :                 combined_items[k].mask = pt->pattern[k].mask;
    2362                 :            :         }
    2363                 :          0 :         combined_items[pt->nb_items].type = RTE_FLOW_ITEM_TYPE_END;
    2364                 :            : 
    2365         [ #  # ]:          0 :         for (k = 0; k < at->nb_actions; k++) {
    2366                 :          0 :                 combined_actions[k].type = at->actions[k].type;
    2367                 :          0 :                 combined_actions[k].conf =
    2368   [ #  #  #  # ]:          0 :                         (actions && actions[k].conf) ? actions[k].conf : at->actions[k].conf;
    2369                 :            :         }
    2370                 :          0 :         combined_actions[at->nb_actions].type = RTE_FLOW_ACTION_TYPE_END;
    2371                 :            : 
    2372                 :            :         memset(&rte_attr, 0, sizeof(rte_attr));
    2373                 :          0 :         rte_attr.priority = table->flow_attr.priority;
    2374                 :          0 :         rte_attr.ingress = table->flow_attr.ingress;
    2375                 :          0 :         rte_attr.egress = table->flow_attr.egress;
    2376                 :          0 :         rte_attr.transfer = table->transfer;
    2377                 :            : 
    2378                 :            :         memset(&in_attr, 0, sizeof(in_attr));
    2379                 :          0 :         rc = cnxk_map_flow_data(eth_dev, &rte_attr, combined_items, combined_actions, &in_attr,
    2380                 :            :                                 in_pattern, in_actions, &in_sample, &flowkey_cfg, &dst_pf_func,
    2381                 :            :                                 &def_action, false, free_allocs, 0);
    2382         [ #  # ]:          0 :         if (rc == 0)
    2383                 :            :                 /* clang-format off */
    2384                 :          0 :                 flow = roc_npc_async_flow_create_by_index_with_pattern(npc, queue,
    2385                 :            :                                 table->roc_table, rule_index, in_pattern, in_actions,
    2386                 :            :                                 user_data, &errcode);
    2387                 :            :         /* clang-format on */
    2388                 :            :         else
    2389                 :            :                 flow = NULL;
    2390                 :            : 
    2391   [ #  #  #  # ]:          0 :         for (j = 0; j < (int)RTE_DIM(free_allocs) && free_allocs[j]; j++)
    2392                 :          0 :                 plt_free((void *)free_allocs[j]);
    2393                 :            : 
    2394         [ #  # ]:          0 :         if (rc != 0) {
    2395                 :          0 :                 rte_flow_error_set(error, rc < 0 ? -rc : rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
    2396                 :            :                                    "Failed to map flow data");
    2397                 :          0 :                 return NULL;
    2398                 :            :         }
    2399         [ #  # ]:          0 :         if (flow == NULL) {
    2400         [ #  # ]:          0 :                 rte_flow_error_set(error, errcode < 0 ? -errcode : EINVAL,
    2401                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "flow parse failed");
    2402                 :          0 :                 return NULL;
    2403                 :            :         }
    2404                 :            : 
    2405                 :            :         return (struct rte_flow *)flow;
    2406                 :            : }
    2407                 :            : 
    2408                 :            : /* Update the actions of an existing flow, keeping key/mask/mcam_id/enable. */
    2409                 :            : int
    2410         [ #  # ]:          0 : cnxk_flow_async_actions_update(struct rte_eth_dev *eth_dev, uint32_t queue,
    2411                 :            :                                const struct rte_flow_op_attr *attr, struct rte_flow *flow,
    2412                 :            :                                const struct rte_flow_action actions[],
    2413                 :            :                                uint8_t action_template_index, void *user_data,
    2414                 :            :                                struct rte_flow_error *error)
    2415                 :            : {
    2416                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2417                 :            :         struct cnxk_flow_actions_template *at;
    2418                 :          0 :         struct roc_npc *npc = &dev->npc;
    2419                 :            :         struct cnxk_flow_table *table;
    2420                 :            : 
    2421                 :          0 :         uint64_t free_allocs[ROC_NPC_MAX_ACTION_COUNT + ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2422                 :          0 :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1] = {0};
    2423                 :            :         struct rte_flow_action combined_actions[ROC_NPC_MAX_ACTION_COUNT];
    2424                 :          0 :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT] = {0};
    2425                 :          0 :         struct roc_npc_action_sample in_sample = {0};
    2426                 :            :         struct rte_flow_item end_pattern[1];
    2427                 :            :         struct rte_flow_attr rte_attr;
    2428                 :            :         struct roc_npc_attr in_attr;
    2429                 :          0 :         uint32_t flowkey_cfg = 0;
    2430                 :          0 :         uint16_t dst_pf_func = 0;
    2431                 :          0 :         uint64_t def_action = 0;
    2432                 :            :         uint16_t k;
    2433                 :            :         int rc, j;
    2434                 :            : 
    2435                 :            :         RTE_SET_USED(attr);
    2436                 :            : 
    2437         [ #  # ]:          0 :         if (flow == NULL)
    2438                 :          0 :                 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    2439                 :            :                                           "bad flow handle");
    2440                 :            : 
    2441                 :            :         /* Recover the cnxk table context from the cookie the engine kept for
    2442                 :            :          * this rule's table.
    2443                 :            :          */
    2444                 :          0 :         table = roc_npc_async_flow_table_cookie((struct roc_npc_template_flow *)flow);
    2445         [ #  # ]:          0 :         if (table == NULL)
    2446                 :          0 :                 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    2447                 :            :                                           "flow handle has no associated table");
    2448         [ #  # ]:          0 :         if (action_template_index >= table->nb_actions_templates)
    2449                 :          0 :                 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    2450                 :            :                                           "actions template index out of range");
    2451                 :            : 
    2452         [ #  # ]:          0 :         at = table->actions_templates[action_template_index];
    2453                 :            : 
    2454                 :            :         if (cnxk_flow_check_actions(at, actions) != 0)
    2455                 :          0 :                 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
    2456                 :            :                                           "actions do not match the selected template");
    2457                 :            : 
    2458         [ #  # ]:          0 :         for (k = 0; k < at->nb_actions; k++) {
    2459                 :          0 :                 combined_actions[k].type = at->actions[k].type;
    2460                 :          0 :                 combined_actions[k].conf =
    2461   [ #  #  #  # ]:          0 :                         (actions && actions[k].conf) ? actions[k].conf : at->actions[k].conf;
    2462                 :            :         }
    2463                 :          0 :         combined_actions[at->nb_actions].type = RTE_FLOW_ACTION_TYPE_END;
    2464                 :            : 
    2465                 :          0 :         end_pattern[0].type = RTE_FLOW_ITEM_TYPE_END;
    2466                 :            : 
    2467                 :            :         memset(&rte_attr, 0, sizeof(rte_attr));
    2468                 :          0 :         rte_attr.priority = table->flow_attr.priority;
    2469                 :          0 :         rte_attr.ingress = table->flow_attr.ingress;
    2470                 :          0 :         rte_attr.egress = table->flow_attr.egress;
    2471                 :          0 :         rte_attr.transfer = table->transfer;
    2472                 :            : 
    2473                 :            :         memset(&in_attr, 0, sizeof(in_attr));
    2474                 :          0 :         rc = cnxk_map_flow_data(eth_dev, &rte_attr, end_pattern, combined_actions, &in_attr,
    2475                 :            :                                 in_pattern, in_actions, &in_sample, &flowkey_cfg, &dst_pf_func,
    2476                 :            :                                 &def_action, false, free_allocs, 0);
    2477         [ #  # ]:          0 :         if (rc == 0)
    2478                 :            :                 /* clang-format off */
    2479                 :          0 :                 rc = roc_npc_async_flow_actions_update(npc, queue,
    2480                 :            :                                 (struct roc_npc_template_flow *)flow, in_actions, user_data);
    2481                 :            :         /* clang-format on */
    2482                 :            : 
    2483   [ #  #  #  # ]:          0 :         for (j = 0; j < (int)RTE_DIM(free_allocs) && free_allocs[j]; j++)
    2484                 :          0 :                 plt_free((void *)free_allocs[j]);
    2485                 :            : 
    2486         [ #  # ]:          0 :         if (rc != 0)
    2487         [ #  # ]:          0 :                 return rte_flow_error_set(error, rc < 0 ? -rc : EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
    2488                 :            :                                           NULL, "failed to update flow actions");
    2489                 :            : 
    2490                 :            :         return 0;
    2491                 :            : }
    2492                 :            : 
    2493                 :            : static int
    2494                 :          0 : cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
    2495                 :            :                    struct rte_flow_error *error)
    2496                 :            : {
    2497                 :          0 :         return cnxk_flow_dev_dump_common(eth_dev, flow, file, error, false);
    2498                 :            : }
    2499                 :            : 
    2500                 :            : static int
    2501         [ #  # ]:          0 : cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context, uint32_t nb_contexts,
    2502                 :            :                          struct rte_flow_error *err)
    2503                 :            : {
    2504                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    2505                 :          0 :         struct roc_npc *roc_npc = &dev->npc;
    2506                 :            :         struct roc_npc_flow_age *flow_age;
    2507                 :            :         uint32_t start_id;
    2508                 :            :         uint32_t end_id;
    2509                 :            :         int cnt = 0;
    2510                 :            :         uint32_t sn;
    2511                 :            :         uint32_t i;
    2512                 :            : 
    2513                 :            :         RTE_SET_USED(err);
    2514                 :            : 
    2515                 :            :         flow_age = &roc_npc->flow_age;
    2516                 :            : 
    2517         [ #  # ]:          0 :         if (!flow_age->age_flow_refcnt)
    2518                 :            :                 return 0;
    2519                 :            : 
    2520                 :            :         do {
    2521                 :            :                 sn = plt_seqcount_read_begin(&flow_age->seq_cnt);
    2522                 :            : 
    2523         [ #  # ]:          0 :                 if (nb_contexts == 0) {
    2524                 :          0 :                         cnt = flow_age->aged_flows_cnt;
    2525                 :            :                 } else {
    2526                 :          0 :                         start_id = flow_age->start_id;
    2527                 :          0 :                         end_id = flow_age->end_id;
    2528         [ #  # ]:          0 :                         for (i = start_id; i <= end_id; i++) {
    2529         [ #  # ]:          0 :                                 if ((int)nb_contexts == cnt)
    2530                 :            :                                         break;
    2531         [ #  # ]:          0 :                                 if (plt_bitmap_get(flow_age->aged_flows, i)) {
    2532                 :          0 :                                         context[cnt] =
    2533                 :          0 :                                                 roc_npc_aged_flow_ctx_get(roc_npc, i);
    2534                 :          0 :                                         cnt++;
    2535                 :            :                                 }
    2536                 :            :                         }
    2537                 :            :                 }
    2538         [ #  # ]:          0 :         } while (plt_seqcount_read_retry(&flow_age->seq_cnt, sn));
    2539                 :            : 
    2540                 :            :         return cnt;
    2541                 :            : }
    2542                 :            : 
    2543                 :            : static int
    2544                 :          0 : cnxk_flow_tunnel_decap_set(__rte_unused struct rte_eth_dev *dev, struct rte_flow_tunnel *tunnel,
    2545                 :            :                            struct rte_flow_action **pmd_actions, uint32_t *num_of_actions,
    2546                 :            :                            __rte_unused struct rte_flow_error *err)
    2547                 :            : {
    2548                 :            :         struct rte_flow_action *nfp_action;
    2549                 :            : 
    2550                 :          0 :         nfp_action = rte_zmalloc("nfp_tun_action", sizeof(struct rte_flow_action), 0);
    2551         [ #  # ]:          0 :         if (nfp_action == NULL) {
    2552                 :          0 :                 plt_err("Alloc memory for nfp tunnel action failed.");
    2553                 :          0 :                 return -ENOMEM;
    2554                 :            :         }
    2555                 :            : 
    2556         [ #  # ]:          0 :         if (tunnel->is_ipv6)
    2557                 :          0 :                 nfp_action->conf = (void *)~0;
    2558                 :            : 
    2559         [ #  # ]:          0 :         switch (tunnel->type) {
    2560                 :          0 :         case RTE_FLOW_ITEM_TYPE_VXLAN:
    2561                 :          0 :                 nfp_action->type = RTE_FLOW_ACTION_TYPE_VXLAN_DECAP;
    2562                 :          0 :                 *pmd_actions = nfp_action;
    2563                 :          0 :                 *num_of_actions = 1;
    2564                 :          0 :                 break;
    2565                 :          0 :         default:
    2566                 :          0 :                 *pmd_actions = NULL;
    2567                 :          0 :                 *num_of_actions = 0;
    2568                 :          0 :                 rte_free(nfp_action);
    2569                 :          0 :                 break;
    2570                 :            :         }
    2571                 :            : 
    2572                 :            :         return 0;
    2573                 :            : }
    2574                 :            : 
    2575                 :            : static int
    2576                 :          0 : cnxk_flow_tunnel_action_decap_release(__rte_unused struct rte_eth_dev *dev,
    2577                 :            :                                       struct rte_flow_action *pmd_actions, uint32_t num_of_actions,
    2578                 :            :                                       __rte_unused struct rte_flow_error *err)
    2579                 :            : {
    2580                 :            :         uint32_t i;
    2581                 :            :         struct rte_flow_action *nfp_action;
    2582                 :            : 
    2583         [ #  # ]:          0 :         for (i = 0; i < num_of_actions; i++) {
    2584                 :          0 :                 nfp_action = &pmd_actions[i];
    2585                 :          0 :                 nfp_action->conf = NULL;
    2586                 :          0 :                 rte_free(nfp_action);
    2587                 :            :         }
    2588                 :            : 
    2589                 :          0 :         return 0;
    2590                 :            : }
    2591                 :            : 
    2592                 :            : static int
    2593                 :          0 : cnxk_flow_tunnel_match(__rte_unused struct rte_eth_dev *dev,
    2594                 :            :                        __rte_unused struct rte_flow_tunnel *tunnel,
    2595                 :            :                        __rte_unused struct rte_flow_item **pmd_items, uint32_t *num_of_items,
    2596                 :            :                        __rte_unused struct rte_flow_error *err)
    2597                 :            : {
    2598                 :          0 :         *num_of_items = 0;
    2599                 :            : 
    2600                 :          0 :         return 0;
    2601                 :            : }
    2602                 :            : 
    2603                 :            : static int
    2604                 :          0 : cnxk_flow_tunnel_item_release(__rte_unused struct rte_eth_dev *dev,
    2605                 :            :                               __rte_unused struct rte_flow_item *pmd_items,
    2606                 :            :                               __rte_unused uint32_t num_of_items,
    2607                 :            :                               __rte_unused struct rte_flow_error *err)
    2608                 :            : {
    2609                 :          0 :         return 0;
    2610                 :            : }
    2611                 :            : 
    2612                 :            : struct rte_flow_ops cnxk_flow_ops = {
    2613                 :            :         .validate = cnxk_flow_validate,
    2614                 :            :         .flush = cnxk_flow_flush,
    2615                 :            :         .query = cnxk_flow_query,
    2616                 :            :         .isolate = cnxk_flow_isolate,
    2617                 :            :         .dev_dump = cnxk_flow_dev_dump,
    2618                 :            :         .get_aged_flows = cnxk_flow_get_aged_flows,
    2619                 :            :         .tunnel_match = cnxk_flow_tunnel_match,
    2620                 :            :         .tunnel_item_release = cnxk_flow_tunnel_item_release,
    2621                 :            :         .tunnel_decap_set = cnxk_flow_tunnel_decap_set,
    2622                 :            :         .tunnel_action_decap_release = cnxk_flow_tunnel_action_decap_release,
    2623                 :            : };

Generated by: LCOV version 1.14