LCOV - code coverage report
Current view: top level - drivers/net/cnxk - cnxk_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 274 0.0 %
Date: 2024-03-01 20:19:12 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 125 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                 :            : 
       6                 :            : const struct cnxk_rte_flow_term_info term[] = {
       7                 :            :         [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH,
       8                 :            :                                     sizeof(struct rte_flow_item_eth)},
       9                 :            :         [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN,
      10                 :            :                                      sizeof(struct rte_flow_item_vlan)},
      11                 :            :         [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG,
      12                 :            :                                       sizeof(struct rte_flow_item_e_tag)},
      13                 :            :         [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4,
      14                 :            :                                      sizeof(struct rte_flow_item_ipv4)},
      15                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6,
      16                 :            :                                      sizeof(struct rte_flow_item_ipv6)},
      17                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = {
      18                 :            :                         ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT,
      19                 :            :                         sizeof(struct rte_flow_item_ipv6_frag_ext)},
      20                 :            :         [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {
      21                 :            :                         ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
      22                 :            :                         sizeof(struct rte_flow_item_arp_eth_ipv4)},
      23                 :            :         [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS,
      24                 :            :                                      sizeof(struct rte_flow_item_mpls)},
      25                 :            :         [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP,
      26                 :            :                                      sizeof(struct rte_flow_item_icmp)},
      27                 :            :         [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP,
      28                 :            :                                     sizeof(struct rte_flow_item_udp)},
      29                 :            :         [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP,
      30                 :            :                                     sizeof(struct rte_flow_item_tcp)},
      31                 :            :         [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP,
      32                 :            :                                      sizeof(struct rte_flow_item_sctp)},
      33                 :            :         [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP,
      34                 :            :                                     sizeof(struct rte_flow_item_esp)},
      35                 :            :         [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE,
      36                 :            :                                     sizeof(struct rte_flow_item_gre)},
      37                 :            :         [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE,
      38                 :            :                                       sizeof(struct rte_flow_item_nvgre)},
      39                 :            :         [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN,
      40                 :            :                                       sizeof(struct rte_flow_item_vxlan)},
      41                 :            :         [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC,
      42                 :            :                                      sizeof(struct rte_flow_item_gtp)},
      43                 :            :         [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU,
      44                 :            :                                      sizeof(struct rte_flow_item_gtp)},
      45                 :            :         [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE,
      46                 :            :                                        sizeof(struct rte_flow_item_geneve)},
      47                 :            :         [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {
      48                 :            :                         ROC_NPC_ITEM_TYPE_VXLAN_GPE,
      49                 :            :                         sizeof(struct rte_flow_item_vxlan_gpe)},
      50                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT,
      51                 :            :                                          sizeof(struct rte_flow_item_ipv6_ext)},
      52                 :            :         [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0},
      53                 :            :         [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
      54                 :            :         [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY,
      55                 :            :                                         sizeof(uint32_t)},
      56                 :            :         [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2,
      57                 :            :                                        sizeof(struct rte_flow_item_higig2_hdr)},
      58                 :            :         [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW,
      59                 :            :                                     sizeof(struct rte_flow_item_raw)},
      60                 :            :         [RTE_FLOW_ITEM_TYPE_MARK] = {ROC_NPC_ITEM_TYPE_MARK,
      61                 :            :                                      sizeof(struct rte_flow_item_mark)},
      62                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_ROUTING_EXT,
      63                 :            :                                      sizeof(struct rte_flow_item_ipv6_routing_ext)},
      64                 :            :         [RTE_FLOW_ITEM_TYPE_TX_QUEUE] = {ROC_NPC_ITEM_TYPE_TX_QUEUE,
      65                 :            :                                      sizeof(struct rte_flow_item_tx_queue)},
      66                 :            :         [RTE_FLOW_ITEM_TYPE_PPPOES] = {ROC_NPC_ITEM_TYPE_PPPOES,
      67                 :            :                                      sizeof(struct rte_flow_item_pppoe)}};
      68                 :            : 
      69                 :            : static int
      70                 :          0 : npc_rss_action_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
      71                 :            :                         const struct rte_flow_action *act)
      72                 :            : {
      73                 :            :         const struct rte_flow_action_rss *rss;
      74                 :            : 
      75                 :          0 :         rss = (const struct rte_flow_action_rss *)act->conf;
      76                 :            : 
      77         [ #  # ]:          0 :         if (attr->egress) {
      78                 :          0 :                 plt_err("No support of RSS in egress");
      79                 :          0 :                 return -EINVAL;
      80                 :            :         }
      81                 :            : 
      82         [ #  # ]:          0 :         if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
      83                 :          0 :                 plt_err("multi-queue mode is disabled");
      84                 :          0 :                 return -ENOTSUP;
      85                 :            :         }
      86                 :            : 
      87   [ #  #  #  # ]:          0 :         if (!rss || !rss->queue_num) {
      88                 :          0 :                 plt_err("no valid queues");
      89                 :          0 :                 return -EINVAL;
      90                 :            :         }
      91                 :            : 
      92         [ #  # ]:          0 :         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
      93                 :          0 :                 plt_err("non-default RSS hash functions are not supported");
      94                 :          0 :                 return -ENOTSUP;
      95                 :            :         }
      96                 :            : 
      97         [ #  # ]:          0 :         if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
      98                 :          0 :                 plt_err("RSS hash key too large");
      99                 :          0 :                 return -ENOTSUP;
     100                 :            :         }
     101                 :            : 
     102                 :            :         return 0;
     103                 :            : }
     104                 :            : 
     105                 :            : static void
     106                 :            : npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev, const struct roc_npc_action *rss_action,
     107                 :            :                     uint32_t *flowkey_cfg, uint64_t default_rss_types)
     108                 :            : {
     109                 :            :         const struct roc_npc_action_rss *rss;
     110                 :            :         uint64_t rss_types;
     111                 :            : 
     112                 :            :         rss = (const struct roc_npc_action_rss *)rss_action->conf;
     113                 :          0 :         rss_types = rss->types;
     114                 :            :         /* If no RSS types are specified, use default one */
     115                 :          0 :         if (rss_types == 0)
     116                 :            :                 rss_types = default_rss_types;
     117                 :            : 
     118                 :          0 :         *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss_types, rss->level);
     119                 :          0 : }
     120                 :            : 
     121                 :            : static int
     122                 :          0 : npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct rte_flow_action *action,
     123                 :            :                          uint16_t *dst_pf_func, uint16_t *dst_channel)
     124                 :            : {
     125                 :            :         const struct rte_flow_action_port_id *port_act;
     126                 :            :         struct rte_eth_dev *portid_eth_dev;
     127                 :            :         char if_name[RTE_ETH_NAME_MAX_LEN];
     128                 :            :         struct cnxk_eth_dev *hw_dst;
     129                 :            :         struct roc_npc *roc_npc_dst;
     130                 :            :         int rc = 0;
     131                 :            : 
     132                 :          0 :         port_act = (const struct rte_flow_action_port_id *)action->conf;
     133                 :            : 
     134                 :          0 :         rc = rte_eth_dev_get_name_by_port(port_act->id, if_name);
     135         [ #  # ]:          0 :         if (rc) {
     136                 :          0 :                 plt_err("Name not found for output port id");
     137                 :          0 :                 goto err_exit;
     138                 :            :         }
     139                 :          0 :         portid_eth_dev = rte_eth_dev_allocated(if_name);
     140         [ #  # ]:          0 :         if (!portid_eth_dev) {
     141                 :          0 :                 plt_err("eth_dev not found for output port id");
     142                 :          0 :                 goto err_exit;
     143                 :            :         }
     144         [ #  # ]:          0 :         if (strcmp(portid_eth_dev->device->driver->name, eth_dev->device->driver->name) != 0) {
     145                 :          0 :                 plt_err("Output port not under same driver");
     146                 :          0 :                 goto err_exit;
     147                 :            :         }
     148                 :          0 :         hw_dst = portid_eth_dev->data->dev_private;
     149                 :            :         roc_npc_dst = &hw_dst->npc;
     150                 :          0 :         *dst_pf_func = roc_npc_dst->pf_func;
     151                 :          0 :         *dst_channel = hw_dst->npc.channel;
     152                 :            : 
     153                 :          0 :         return 0;
     154                 :            : 
     155                 :            : err_exit:
     156                 :            :         return -EINVAL;
     157                 :            : }
     158                 :            : 
     159                 :            : static int
     160                 :          0 : roc_npc_parse_sample_subaction(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[],
     161                 :            :                                struct roc_npc_action_sample *sample_action)
     162                 :            : {
     163                 :          0 :         uint16_t dst_pf_func = 0, dst_channel = 0;
     164                 :            :         const struct roc_npc_action_vf *vf_act;
     165                 :            :         int rc = 0, count = 0;
     166                 :            :         bool is_empty = true;
     167                 :            : 
     168         [ #  # ]:          0 :         if (sample_action->ratio != 1) {
     169                 :          0 :                 plt_err("Sample ratio must be 1");
     170                 :          0 :                 return -EINVAL;
     171                 :            :         }
     172                 :            : 
     173         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     174                 :            :                 is_empty = false;
     175   [ #  #  #  # ]:          0 :                 switch (actions->type) {
     176                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PF:
     177                 :          0 :                         count++;
     178                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_PF;
     179                 :          0 :                         break;
     180                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VF:
     181                 :          0 :                         count++;
     182                 :          0 :                         vf_act = (const struct roc_npc_action_vf *)actions->conf;
     183                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_VF;
     184                 :          0 :                         sample_action->pf_func = vf_act->id & NPC_PFVF_FUNC_MASK;
     185                 :          0 :                         break;
     186                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
     187                 :          0 :                         rc = npc_parse_port_id_action(eth_dev, actions, &dst_pf_func, &dst_channel);
     188         [ #  # ]:          0 :                         if (rc)
     189                 :            :                                 return -EINVAL;
     190                 :            : 
     191                 :          0 :                         count++;
     192                 :          0 :                         sample_action->action_type |= ROC_NPC_ACTION_TYPE_PORT_ID;
     193                 :          0 :                         sample_action->pf_func = dst_pf_func;
     194                 :          0 :                         sample_action->channel = dst_channel;
     195                 :          0 :                         break;
     196                 :          0 :                 default:
     197                 :          0 :                         continue;
     198                 :            :                 }
     199                 :            :         }
     200                 :            : 
     201         [ #  # ]:          0 :         if (count > 1 || is_empty)
     202                 :          0 :                 return -EINVAL;
     203                 :            : 
     204                 :            :         return 0;
     205                 :            : }
     206                 :            : 
     207                 :            : static int
     208                 :          0 : cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     209                 :            :                  const struct rte_flow_action actions[], struct roc_npc_action in_actions[],
     210                 :            :                  struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
     211                 :            :                  uint16_t *dst_pf_func)
     212                 :            : {
     213                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     214                 :            :         const struct rte_flow_action_queue *act_q = NULL;
     215                 :            :         const struct rte_flow_action_ethdev *act_ethdev;
     216                 :            :         const struct rte_flow_action_sample *act_sample;
     217                 :            :         const struct rte_flow_action_port_id *port_act;
     218                 :            :         struct rte_eth_dev *portid_eth_dev;
     219                 :            :         char if_name[RTE_ETH_NAME_MAX_LEN];
     220                 :            :         struct cnxk_eth_dev *hw_dst;
     221                 :            :         struct roc_npc *roc_npc_dst;
     222                 :            :         bool is_vf_action = false;
     223                 :            :         int i = 0, rc = 0;
     224                 :            :         int rq;
     225                 :            : 
     226         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     227   [ #  #  #  #  :          0 :                 switch (actions->type) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     228                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VOID:
     229                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
     230                 :          0 :                         break;
     231                 :            : 
     232                 :          0 :                 case RTE_FLOW_ACTION_TYPE_MARK:
     233                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
     234                 :          0 :                         in_actions[i].conf = actions->conf;
     235                 :          0 :                         break;
     236                 :            : 
     237                 :          0 :                 case RTE_FLOW_ACTION_TYPE_FLAG:
     238                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
     239                 :          0 :                         break;
     240                 :            : 
     241                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
     242                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
     243                 :          0 :                         break;
     244                 :            : 
     245                 :          0 :                 case RTE_FLOW_ACTION_TYPE_DROP:
     246                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
     247                 :          0 :                         break;
     248                 :            : 
     249                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PF:
     250                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
     251                 :          0 :                         break;
     252                 :            : 
     253                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VF:
     254                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
     255                 :          0 :                         in_actions[i].conf = actions->conf;
     256                 :            :                         is_vf_action = true;
     257                 :          0 :                         break;
     258                 :            : 
     259                 :          0 :                 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
     260                 :            :                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
     261                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
     262                 :          0 :                         in_actions[i].conf = actions->conf;
     263                 :            :                         act_ethdev = (const struct rte_flow_action_ethdev *)
     264                 :            :                                            actions->conf;
     265                 :            :                         port_act = (const struct rte_flow_action_port_id *)
     266                 :            :                                            actions->conf;
     267   [ #  #  #  # ]:          0 :                         if (rte_eth_dev_get_name_by_port(
     268                 :            :                             actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
     269                 :          0 :                             act_ethdev->port_id : port_act->id, if_name)) {
     270                 :          0 :                                 plt_err("Name not found for output port id");
     271                 :          0 :                                 goto err_exit;
     272                 :            :                         }
     273                 :          0 :                         portid_eth_dev = rte_eth_dev_allocated(if_name);
     274         [ #  # ]:          0 :                         if (!portid_eth_dev) {
     275                 :          0 :                                 plt_err("eth_dev not found for output port id");
     276                 :          0 :                                 goto err_exit;
     277                 :            :                         }
     278                 :          0 :                         if (strcmp(portid_eth_dev->device->driver->name,
     279         [ #  # ]:          0 :                                    eth_dev->device->driver->name) != 0) {
     280                 :          0 :                                 plt_err("Output port not under same driver");
     281                 :          0 :                                 goto err_exit;
     282                 :            :                         }
     283                 :          0 :                         hw_dst = portid_eth_dev->data->dev_private;
     284                 :            :                         roc_npc_dst = &hw_dst->npc;
     285                 :          0 :                         *dst_pf_func = roc_npc_dst->pf_func;
     286                 :          0 :                         break;
     287                 :            : 
     288                 :          0 :                 case RTE_FLOW_ACTION_TYPE_QUEUE:
     289                 :          0 :                         act_q = (const struct rte_flow_action_queue *)actions->conf;
     290                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
     291                 :          0 :                         in_actions[i].conf = actions->conf;
     292                 :          0 :                         break;
     293                 :            : 
     294                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
     295                 :          0 :                         rc = npc_rss_action_validate(eth_dev, attr, actions);
     296         [ #  # ]:          0 :                         if (rc)
     297                 :          0 :                                 goto err_exit;
     298                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
     299                 :          0 :                         in_actions[i].conf = actions->conf;
     300                 :          0 :                         npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg,
     301         [ #  # ]:          0 :                                             eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);
     302                 :            :                         break;
     303                 :            : 
     304                 :          0 :                 case RTE_FLOW_ACTION_TYPE_SECURITY:
     305                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
     306                 :          0 :                         in_actions[i].conf = actions->conf;
     307                 :          0 :                         break;
     308                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
     309                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
     310                 :          0 :                         break;
     311                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
     312                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
     313                 :          0 :                         in_actions[i].conf = actions->conf;
     314                 :          0 :                         break;
     315                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
     316                 :          0 :                         in_actions[i].type =
     317                 :            :                                 ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
     318                 :          0 :                         in_actions[i].conf = actions->conf;
     319                 :          0 :                         break;
     320                 :          0 :                 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
     321                 :          0 :                         in_actions[i].type =
     322                 :            :                                 ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
     323                 :          0 :                         in_actions[i].conf = actions->conf;
     324                 :          0 :                         break;
     325                 :          0 :                 case RTE_FLOW_ACTION_TYPE_METER:
     326                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_METER;
     327                 :          0 :                         in_actions[i].conf = actions->conf;
     328                 :          0 :                         break;
     329                 :          0 :                 case RTE_FLOW_ACTION_TYPE_AGE:
     330                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE;
     331                 :          0 :                         in_actions[i].conf = actions->conf;
     332                 :          0 :                         break;
     333                 :          0 :                 case RTE_FLOW_ACTION_TYPE_SAMPLE:
     334                 :          0 :                         act_sample = actions->conf;
     335                 :          0 :                         in_sample_actions->ratio = act_sample->ratio;
     336                 :          0 :                         rc = roc_npc_parse_sample_subaction(eth_dev, act_sample->actions,
     337                 :            :                                                             in_sample_actions);
     338         [ #  # ]:          0 :                         if (rc) {
     339                 :          0 :                                 plt_err("Sample subaction parsing failed.");
     340                 :          0 :                                 goto err_exit;
     341                 :            :                         }
     342                 :            : 
     343                 :          0 :                         in_actions[i].type = ROC_NPC_ACTION_TYPE_SAMPLE;
     344                 :          0 :                         in_actions[i].conf = in_sample_actions;
     345                 :          0 :                         break;
     346                 :          0 :                 default:
     347                 :          0 :                         plt_npc_dbg("Action is not supported = %d", actions->type);
     348                 :          0 :                         goto err_exit;
     349                 :            :                 }
     350                 :          0 :                 i++;
     351                 :            :         }
     352                 :            : 
     353         [ #  # ]:          0 :         if (!is_vf_action && act_q) {
     354                 :          0 :                 rq = act_q->index;
     355         [ #  # ]:          0 :                 if (rq >= eth_dev->data->nb_rx_queues) {
     356                 :          0 :                         plt_npc_dbg("Invalid queue index");
     357                 :          0 :                         goto err_exit;
     358                 :            :                 }
     359                 :            :         }
     360                 :          0 :         in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
     361                 :          0 :         return 0;
     362                 :            : 
     363                 :            : err_exit:
     364                 :            :         return -EINVAL;
     365                 :            : }
     366                 :            : 
     367                 :            : static int
     368                 :          0 : cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     369                 :            :                    const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
     370                 :            :                    struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[],
     371                 :            :                    struct roc_npc_action in_actions[],
     372                 :            :                    struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg,
     373                 :            :                    uint16_t *dst_pf_func)
     374                 :            : {
     375                 :            :         int i = 0;
     376                 :            : 
     377                 :          0 :         in_attr->priority = attr->priority;
     378                 :          0 :         in_attr->ingress = attr->ingress;
     379                 :          0 :         in_attr->egress = attr->egress;
     380                 :            : 
     381         [ #  # ]:          0 :         while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
     382                 :          0 :                 in_pattern[i].spec = pattern->spec;
     383                 :          0 :                 in_pattern[i].last = pattern->last;
     384                 :          0 :                 in_pattern[i].mask = pattern->mask;
     385                 :          0 :                 in_pattern[i].type = term[pattern->type].item_type;
     386                 :          0 :                 in_pattern[i].size = term[pattern->type].item_size;
     387                 :          0 :                 pattern++;
     388                 :          0 :                 i++;
     389                 :            :         }
     390                 :          0 :         in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
     391                 :            : 
     392                 :          0 :         return cnxk_map_actions(eth_dev, attr, actions, in_actions, in_sample_actions, flowkey_cfg,
     393                 :            :                                 dst_pf_func);
     394                 :            : }
     395                 :            : 
     396                 :            : static int
     397         [ #  # ]:          0 : cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     398                 :            :                    const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
     399                 :            :                    struct rte_flow_error *error)
     400                 :            : {
     401                 :            :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
     402                 :            :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
     403                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     404                 :            :         struct roc_npc_action_sample in_sample_action;
     405                 :          0 :         struct roc_npc *npc = &dev->npc;
     406                 :            :         struct roc_npc_attr in_attr;
     407                 :            :         struct roc_npc_flow flow;
     408                 :          0 :         uint32_t flowkey_cfg = 0;
     409                 :          0 :         uint16_t dst_pf_func = 0;
     410                 :            :         int rc;
     411                 :            : 
     412                 :            :         /* Skip flow validation for MACsec. */
     413   [ #  #  #  # ]:          0 :         if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
     414                 :          0 :             cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL)
     415                 :            :                 return 0;
     416                 :            : 
     417                 :            :         memset(&flow, 0, sizeof(flow));
     418                 :            :         memset(&in_sample_action, 0, sizeof(in_sample_action));
     419                 :          0 :         flow.is_validate = true;
     420                 :            : 
     421                 :          0 :         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
     422                 :            :                                 &in_sample_action, &flowkey_cfg, &dst_pf_func);
     423         [ #  # ]:          0 :         if (rc) {
     424                 :          0 :                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     425                 :            :                                    "Failed to map flow data");
     426                 :          0 :                 return rc;
     427                 :            :         }
     428                 :            : 
     429                 :          0 :         rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
     430                 :            : 
     431         [ #  # ]:          0 :         if (rc) {
     432                 :          0 :                 rte_flow_error_set(error, 0, rc, NULL,
     433                 :            :                                    "Flow validation failed");
     434                 :          0 :                 return rc;
     435                 :            :         }
     436                 :            :         return 0;
     437                 :            : }
     438                 :            : 
     439                 :            : struct roc_npc_flow *
     440                 :          0 : cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
     441                 :            :                  const struct rte_flow_item pattern[],
     442                 :            :                  const struct rte_flow_action actions[],
     443                 :            :                  struct rte_flow_error *error)
     444                 :            : {
     445                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     446                 :            :         struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
     447                 :            :         struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
     448                 :            :         struct roc_npc_action_sample in_sample_action;
     449                 :          0 :         struct roc_npc *npc = &dev->npc;
     450                 :            :         struct roc_npc_attr in_attr;
     451                 :            :         struct roc_npc_flow *flow;
     452                 :          0 :         uint16_t dst_pf_func = 0;
     453                 :          0 :         int errcode = 0;
     454                 :            :         int rc;
     455                 :            : 
     456                 :            :         memset(&in_sample_action, 0, sizeof(in_sample_action));
     457                 :          0 :         rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions,
     458                 :            :                                 &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func);
     459         [ #  # ]:          0 :         if (rc) {
     460                 :          0 :                 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
     461                 :            :                                    "Failed to map flow data");
     462                 :          0 :                 return NULL;
     463                 :            :         }
     464                 :            : 
     465                 :          0 :         flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions, dst_pf_func, &errcode);
     466         [ #  # ]:          0 :         if (errcode != 0) {
     467                 :          0 :                 rte_flow_error_set(error, errcode, errcode, NULL, roc_error_msg_get(errcode));
     468                 :          0 :                 return NULL;
     469                 :            :         }
     470                 :            : 
     471                 :            :         return flow;
     472                 :            : }
     473                 :            : 
     474                 :            : int
     475                 :          0 : cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
     476                 :            :                   struct rte_flow_error *error)
     477                 :            : {
     478                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     479                 :          0 :         struct roc_npc *npc = &dev->npc;
     480                 :            :         int rc;
     481                 :            : 
     482                 :          0 :         rc = roc_npc_flow_destroy(npc, flow);
     483         [ #  # ]:          0 :         if (rc)
     484                 :          0 :                 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     485                 :            :                                    NULL, "Flow Destroy failed");
     486                 :          0 :         return rc;
     487                 :            : }
     488                 :            : 
     489                 :            : static int
     490                 :          0 : cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
     491                 :            : {
     492                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     493                 :          0 :         struct roc_npc *npc = &dev->npc;
     494                 :            :         int rc;
     495                 :            : 
     496                 :          0 :         rc = roc_npc_mcam_free_all_resources(npc);
     497         [ #  # ]:          0 :         if (rc) {
     498                 :          0 :                 rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     499                 :            :                                    NULL, "Failed to flush filter");
     500                 :          0 :                 return -rte_errno;
     501                 :            :         }
     502                 :            : 
     503                 :            :         return 0;
     504                 :            : }
     505                 :            : 
     506                 :            : static int
     507         [ #  # ]:          0 : cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
     508                 :            :                 const struct rte_flow_action *action, void *data,
     509                 :            :                 struct rte_flow_error *error)
     510                 :            : {
     511                 :            :         struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
     512                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     513                 :          0 :         struct roc_npc *npc = &dev->npc;
     514                 :            :         struct rte_flow_query_count *query = data;
     515                 :            :         const char *errmsg = NULL;
     516                 :            :         int errcode = ENOTSUP;
     517                 :            :         int rc;
     518                 :            : 
     519         [ #  # ]:          0 :         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
     520                 :            :                 errmsg = "Only COUNT is supported in query";
     521                 :          0 :                 goto err_exit;
     522                 :            :         }
     523                 :            : 
     524         [ #  # ]:          0 :         if (in_flow->ctr_id == NPC_COUNTER_NONE) {
     525                 :            :                 errmsg = "Counter is not available";
     526                 :          0 :                 goto err_exit;
     527                 :            :         }
     528                 :            : 
     529         [ #  # ]:          0 :         if (in_flow->use_pre_alloc)
     530                 :          0 :                 rc = roc_npc_inl_mcam_read_counter(in_flow->ctr_id, &query->hits);
     531                 :            :         else
     532                 :          0 :                 rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
     533         [ #  # ]:          0 :         if (rc != 0) {
     534                 :            :                 errcode = EIO;
     535                 :            :                 errmsg = "Error reading flow counter";
     536                 :          0 :                 goto err_exit;
     537                 :            :         }
     538                 :          0 :         query->hits_set = 1;
     539                 :          0 :         query->bytes_set = 0;
     540                 :            : 
     541         [ #  # ]:          0 :         if (query->reset) {
     542         [ #  # ]:          0 :                 if (in_flow->use_pre_alloc)
     543                 :          0 :                         rc = roc_npc_inl_mcam_clear_counter(in_flow->ctr_id);
     544                 :            :                 else
     545                 :          0 :                         rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
     546                 :            :         }
     547         [ #  # ]:          0 :         if (rc != 0) {
     548                 :            :                 errcode = EIO;
     549                 :            :                 errmsg = "Error clearing flow counter";
     550                 :          0 :                 goto err_exit;
     551                 :            :         }
     552                 :            : 
     553                 :            :         return 0;
     554                 :            : 
     555                 :          0 : err_exit:
     556                 :          0 :         rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     557                 :            :                            NULL, errmsg);
     558                 :          0 :         return -rte_errno;
     559                 :            : }
     560                 :            : 
     561                 :            : static int
     562                 :          0 : cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
     563                 :            :                   int enable __rte_unused, struct rte_flow_error *error)
     564                 :            : {
     565                 :            :         /* If we support, we need to un-install the default mcam
     566                 :            :          * entry for this port.
     567                 :            :          */
     568                 :            : 
     569                 :          0 :         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     570                 :            :                            NULL, "Flow isolation not supported");
     571                 :            : 
     572                 :          0 :         return -rte_errno;
     573                 :            : }
     574                 :            : 
     575                 :            : static int
     576         [ #  # ]:          0 : cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
     577                 :            :                    FILE *file, struct rte_flow_error *error)
     578                 :            : {
     579                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     580                 :          0 :         struct roc_npc *npc = &dev->npc;
     581                 :            : 
     582         [ #  # ]:          0 :         if (file == NULL) {
     583                 :          0 :                 rte_flow_error_set(error, EINVAL,
     584                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     585                 :            :                                    "Invalid file");
     586                 :          0 :                 return -rte_errno;
     587                 :            :         }
     588                 :            : 
     589         [ #  # ]:          0 :         if (flow != NULL) {
     590                 :          0 :                 rte_flow_error_set(error, EINVAL,
     591                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE,
     592                 :            :                                    NULL,
     593                 :            :                                    "Invalid argument");
     594                 :          0 :                 return -EINVAL;
     595                 :            :         }
     596                 :            : 
     597                 :          0 :         roc_npc_flow_dump(file, npc);
     598                 :            : 
     599                 :          0 :         return 0;
     600                 :            : }
     601                 :            : 
     602                 :            : static int
     603         [ #  # ]:          0 : cnxk_flow_get_aged_flows(struct rte_eth_dev *eth_dev, void **context,
     604                 :            :                          uint32_t nb_contexts, struct rte_flow_error *err)
     605                 :            : {
     606                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     607                 :          0 :         struct roc_npc *roc_npc = &dev->npc;
     608                 :            :         struct roc_npc_flow_age *flow_age;
     609                 :            :         uint32_t start_id;
     610                 :            :         uint32_t end_id;
     611                 :            :         int cnt = 0;
     612                 :            :         uint32_t sn;
     613                 :            :         uint32_t i;
     614                 :            : 
     615                 :            :         RTE_SET_USED(err);
     616                 :            : 
     617                 :            :         flow_age = &roc_npc->flow_age;
     618                 :            : 
     619         [ #  # ]:          0 :         if (!flow_age->age_flow_refcnt)
     620                 :            :                 return 0;
     621                 :            : 
     622                 :            :         do {
     623                 :            :                 sn = plt_seqcount_read_begin(&flow_age->seq_cnt);
     624                 :            : 
     625         [ #  # ]:          0 :                 if (nb_contexts == 0) {
     626                 :          0 :                         cnt = flow_age->aged_flows_cnt;
     627                 :            :                 } else {
     628                 :          0 :                         start_id = flow_age->start_id;
     629                 :          0 :                         end_id = flow_age->end_id;
     630         [ #  # ]:          0 :                         for (i = start_id; i <= end_id; i++) {
     631         [ #  # ]:          0 :                                 if ((int)nb_contexts == cnt)
     632                 :            :                                         break;
     633         [ #  # ]:          0 :                                 if (plt_bitmap_get(flow_age->aged_flows, i)) {
     634                 :          0 :                                         context[cnt] =
     635                 :          0 :                                                 roc_npc_aged_flow_ctx_get(roc_npc, i);
     636                 :          0 :                                         cnt++;
     637                 :            :                                 }
     638                 :            :                         }
     639                 :            :                 }
     640         [ #  # ]:          0 :         } while (plt_seqcount_read_retry(&flow_age->seq_cnt, sn));
     641                 :            : 
     642                 :            :         return cnt;
     643                 :            : }
     644                 :            : 
     645                 :            : struct rte_flow_ops cnxk_flow_ops = {
     646                 :            :         .validate = cnxk_flow_validate,
     647                 :            :         .flush = cnxk_flow_flush,
     648                 :            :         .query = cnxk_flow_query,
     649                 :            :         .isolate = cnxk_flow_isolate,
     650                 :            :         .dev_dump = cnxk_flow_dev_dump,
     651                 :            :         .get_aged_flows = cnxk_flow_get_aged_flows,
     652                 :            : };

Generated by: LCOV version 1.14