LCOV - code coverage report
Current view: top level - drivers/net/cpfl - cpfl_flow_engine_fxp.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 3 276 1.1 %
Date: 2024-01-22 16:26:08 Functions: 1 13 7.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 150 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2022 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <sys/queue.h>
       6                 :            : #include <stdio.h>
       7                 :            : #include <errno.h>
       8                 :            : #include <stdint.h>
       9                 :            : #include <string.h>
      10                 :            : #include <unistd.h>
      11                 :            : #include <stdarg.h>
      12                 :            : #include <math.h>
      13                 :            : #include <rte_debug.h>
      14                 :            : #include <rte_ether.h>
      15                 :            : #include <rte_log.h>
      16                 :            : #include <rte_malloc.h>
      17                 :            : #include <rte_eth_ctrl.h>
      18                 :            : #include <rte_tailq.h>
      19                 :            : #include <rte_flow_driver.h>
      20                 :            : #include <rte_flow.h>
      21                 :            : #include <rte_bitmap.h>
      22                 :            : #include <ethdev_driver.h>
      23                 :            : #include "cpfl_rules.h"
      24                 :            : #include "cpfl_logs.h"
      25                 :            : #include "cpfl_ethdev.h"
      26                 :            : #include "cpfl_flow.h"
      27                 :            : #include "cpfl_fxp_rule.h"
      28                 :            : #include "cpfl_flow_parser.h"
      29                 :            : 
      30                 :            : #define CPFL_COOKIE_DEF         0x1000
      31                 :            : #define CPFL_MOD_COOKIE_DEF     0x1237561
      32                 :            : #define CPFL_PREC_DEF           1
      33                 :            : #define CPFL_PREC_SET           5
      34                 :            : #define CPFL_TYPE_ID            3
      35                 :            : #define CPFL_OFFSET             0x0a
      36                 :            : #define CPFL_HOST_ID_DEF        0
      37                 :            : #define CPFL_PF_NUM_DEF         0
      38                 :            : #define CPFL_PORT_NUM_DEF       0
      39                 :            : #define CPFL_RESP_REQ_DEF       2
      40                 :            : #define CPFL_PIN_TO_CACHE_DEF   0
      41                 :            : #define CPFL_CLEAR_MIRROR_1ST_STATE_DEF 0
      42                 :            : #define CPFL_FIXED_FETCH_DEF    0
      43                 :            : #define CPFL_PTI_DEF            0
      44                 :            : #define CPFL_MOD_OBJ_SIZE_DEF   0
      45                 :            : #define CPFL_PIN_MOD_CONTENT_DEF        0
      46                 :            : 
      47                 :            : #define CPFL_MAX_MOD_CONTENT_INDEX      256
      48                 :            : #define CPFL_MAX_MR_ACTION_NUM  8
      49                 :            : 
      50                 :            : /* Struct used when parse detailed rule information with json file */
      51                 :            : struct cpfl_rule_info_meta {
      52                 :            :         struct cpfl_flow_pr_action pr_action;   /* json action field of pattern rule */
      53                 :            :         uint32_t pr_num;                        /* number of pattern rules */
      54                 :            :         uint32_t mr_num;                        /* number of modification rules */
      55                 :            :         uint32_t rule_num;                      /* number of all rules */
      56                 :            :         struct cpfl_rule_info rules[0];
      57                 :            : };
      58                 :            : 
      59                 :            : static uint32_t cpfl_fxp_mod_idx_alloc(struct cpfl_adapter_ext *ad);
      60                 :            : static void cpfl_fxp_mod_idx_free(struct cpfl_adapter_ext *ad, uint32_t idx);
      61                 :            : uint64_t cpfl_rule_cookie = CPFL_COOKIE_DEF;
      62                 :            : 
      63                 :            : static int
      64                 :          0 : cpfl_fxp_create(struct rte_eth_dev *dev,
      65                 :            :                 struct rte_flow *flow,
      66                 :            :                 void *meta,
      67                 :            :                 struct rte_flow_error *error)
      68                 :            : {
      69                 :            :         int ret = 0;
      70                 :            :         uint32_t cpq_id = 0;
      71                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
      72                 :          0 :         struct cpfl_adapter_ext *ad = itf->adapter;
      73                 :            :         struct cpfl_rule_info_meta *rim = meta;
      74                 :            :         struct cpfl_vport *vport;
      75                 :            :         struct cpfl_repr *repr;
      76                 :            : 
      77         [ #  # ]:          0 :         if (!rim)
      78                 :            :                 return ret;
      79                 :            : 
      80         [ #  # ]:          0 :         if (itf->type == CPFL_ITF_TYPE_VPORT) {
      81                 :            :                 vport = (struct cpfl_vport *)itf;
      82                 :            :                 /* Every vport has one pair control queues configured to handle message.
      83                 :            :                  * Even index is tx queue and odd index is rx queue.
      84                 :            :                  */
      85                 :          0 :                 cpq_id = vport->base.devarg_id * 2;
      86         [ #  # ]:          0 :         } else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
      87                 :            :                 repr = (struct cpfl_repr *)itf;
      88                 :          0 :                 cpq_id = ((repr->repr_id.pf_id  + repr->repr_id.vf_id) &
      89                 :          0 :                           (CPFL_TX_CFGQ_NUM - 1)) * 2;
      90                 :            :         } else {
      91                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
      92                 :            :                                    "fail to find correct control queue");
      93                 :          0 :                 return -rte_errno;
      94                 :            :         }
      95                 :            : 
      96                 :          0 :         ret = cpfl_rule_process(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1],
      97                 :          0 :                                 rim->rules, rim->rule_num, true);
      98         [ #  # ]:          0 :         if (ret < 0) {
      99                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     100                 :            :                                    "cpfl filter create flow fail");
     101                 :          0 :                 rte_free(rim);
     102                 :          0 :                 return ret;
     103                 :            :         }
     104                 :            : 
     105                 :          0 :         flow->rule = rim;
     106                 :            : 
     107                 :          0 :         return ret;
     108                 :            : }
     109                 :            : 
     110                 :            : static int
     111                 :          0 : cpfl_fxp_destroy(struct rte_eth_dev *dev,
     112                 :            :                  struct rte_flow *flow,
     113                 :            :                  struct rte_flow_error *error)
     114                 :            : {
     115                 :            :         int ret = 0;
     116                 :            :         uint32_t cpq_id = 0;
     117                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
     118                 :          0 :         struct cpfl_adapter_ext *ad = itf->adapter;
     119                 :            :         struct cpfl_rule_info_meta *rim;
     120                 :            :         uint32_t i;
     121                 :            :         struct cpfl_vport *vport;
     122                 :            :         struct cpfl_repr *repr;
     123                 :            : 
     124                 :          0 :         rim = (struct cpfl_rule_info_meta *)flow->rule;
     125         [ #  # ]:          0 :         if (!rim) {
     126                 :          0 :                 rte_flow_error_set(error, EINVAL,
     127                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     128                 :            :                                    "no such flow create by cpfl filter");
     129                 :            : 
     130                 :          0 :                 return -rte_errno;
     131                 :            :         }
     132                 :            : 
     133         [ #  # ]:          0 :         if (itf->type == CPFL_ITF_TYPE_VPORT) {
     134                 :            :                 vport = (struct cpfl_vport *)itf;
     135                 :          0 :                 cpq_id = vport->base.devarg_id * 2;
     136         [ #  # ]:          0 :         } else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
     137                 :            :                 repr = (struct cpfl_repr *)itf;
     138                 :          0 :                 cpq_id = ((repr->repr_id.pf_id  + repr->repr_id.vf_id) &
     139                 :          0 :                           (CPFL_TX_CFGQ_NUM - 1)) * 2;
     140                 :            :         } else {
     141                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     142                 :            :                                    "fail to find correct control queue");
     143                 :          0 :                 ret = -rte_errno;
     144                 :          0 :                 goto err;
     145                 :            :         }
     146                 :            : 
     147                 :          0 :         ret = cpfl_rule_process(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1], rim->rules,
     148                 :          0 :                                 rim->rule_num, false);
     149         [ #  # ]:          0 :         if (ret < 0) {
     150                 :          0 :                 rte_flow_error_set(error, EINVAL,
     151                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     152                 :            :                                    "fail to destroy cpfl filter rule");
     153                 :          0 :                 goto err;
     154                 :            :         }
     155                 :            : 
     156                 :            :         /* free mod index */
     157         [ #  # ]:          0 :         for (i = rim->pr_num; i < rim->rule_num; i++)
     158                 :          0 :                 cpfl_fxp_mod_idx_free(ad, rim->rules[i].mod.mod_index);
     159                 :          0 : err:
     160                 :          0 :         rte_free(rim);
     161                 :          0 :         flow->rule = NULL;
     162                 :          0 :         return ret;
     163                 :            : }
     164                 :            : 
     165                 :            : static bool
     166                 :          0 : cpfl_fxp_parse_pattern(const struct cpfl_flow_pr_action *pr_action,
     167                 :            :                        struct cpfl_rule_info_meta *rim,
     168                 :            :                        int i)
     169                 :            : {
     170         [ #  # ]:          0 :         if (pr_action->type == CPFL_JS_PR_ACTION_TYPE_SEM) {
     171                 :            :                 struct cpfl_rule_info *rinfo = &rim->rules[i];
     172                 :            : 
     173                 :          0 :                 rinfo->type = CPFL_RULE_TYPE_SEM;
     174                 :          0 :                 rinfo->sem.prof_id = pr_action->sem.prof;
     175                 :          0 :                 rinfo->sem.sub_prof_id = pr_action->sem.subprof;
     176                 :          0 :                 rinfo->sem.key_byte_len = pr_action->sem.keysize;
     177                 :          0 :                 memcpy(rinfo->sem.key, pr_action->sem.cpfl_flow_pr_fv, rinfo->sem.key_byte_len);
     178                 :          0 :                 rinfo->sem.pin_to_cache = CPFL_PIN_TO_CACHE_DEF;
     179                 :          0 :                 rinfo->sem.fixed_fetch = CPFL_FIXED_FETCH_DEF;
     180                 :            :         } else {
     181                 :          0 :                 PMD_DRV_LOG(ERR, "Invalid pattern item.");
     182                 :          0 :                 return false;
     183                 :            :         }
     184                 :            : 
     185                 :          0 :         return true;
     186                 :            : }
     187                 :            : 
     188                 :            : static int
     189                 :          0 : cpfl_parse_mod_content(struct cpfl_adapter_ext *adapter,
     190                 :            :                        struct cpfl_rule_info *match_rinfo,
     191                 :            :                        struct cpfl_rule_info *mod_rinfo,
     192                 :            :                        const struct cpfl_flow_mr_action *mr_action)
     193                 :            : {
     194                 :            :         struct cpfl_mod_rule_info *minfo = &mod_rinfo->mod;
     195                 :            :         uint32_t mod_idx;
     196                 :            :         int i;
     197                 :          0 :         int next = match_rinfo->act_byte_len / (sizeof(union cpfl_action_set));
     198                 :          0 :         union cpfl_action_set *act_set =
     199                 :          0 :                 &((union cpfl_action_set *)match_rinfo->act_bytes)[next];
     200                 :            : 
     201   [ #  #  #  # ]:          0 :         if (!mr_action || mr_action->type != CPFL_JS_MR_ACTION_TYPE_MOD)
     202                 :            :                 return -EINVAL;
     203                 :            : 
     204                 :          0 :         *act_set = cpfl_act_mod_profile(CPFL_PREC_DEF,
     205         [ #  # ]:          0 :                                         mr_action->mod.prof,
     206                 :            :                                         CPFL_PTI_DEF,
     207                 :            :                                         0, /* append */
     208                 :            :                                         0, /* prepend */
     209                 :            :                                         CPFL_ACT_MOD_PROFILE_PREFETCH_256B);
     210                 :            : 
     211                 :            :         act_set++;
     212                 :          0 :         match_rinfo->act_byte_len += sizeof(union cpfl_action_set);
     213                 :            : 
     214                 :          0 :         mod_idx = cpfl_fxp_mod_idx_alloc(adapter);
     215         [ #  # ]:          0 :         if (mod_idx == CPFL_MAX_MOD_CONTENT_INDEX) {
     216                 :          0 :                 PMD_DRV_LOG(ERR, "Out of Mod Index.");
     217                 :          0 :                 return -ENOMEM;
     218                 :            :         }
     219                 :            : 
     220                 :          0 :         *act_set = cpfl_act_mod_addr(CPFL_PREC_DEF, mod_idx);
     221                 :            : 
     222                 :            :         act_set++;
     223                 :          0 :         match_rinfo->act_byte_len += sizeof(union cpfl_action_set);
     224                 :            : 
     225                 :          0 :         mod_rinfo->type = CPFL_RULE_TYPE_MOD;
     226                 :          0 :         minfo->mod_obj_size = CPFL_MOD_OBJ_SIZE_DEF;
     227                 :          0 :         minfo->pin_mod_content = CPFL_PIN_MOD_CONTENT_DEF;
     228                 :          0 :         minfo->mod_index = mod_idx;
     229                 :          0 :         mod_rinfo->cookie = CPFL_MOD_COOKIE_DEF;
     230                 :          0 :         mod_rinfo->port_num = CPFL_PORT_NUM_DEF;
     231                 :          0 :         mod_rinfo->resp_req = CPFL_RESP_REQ_DEF;
     232                 :            : 
     233                 :          0 :         minfo->mod_content_byte_len = mr_action->mod.byte_len + 2;
     234         [ #  # ]:          0 :         for (i = 0; i < minfo->mod_content_byte_len; i++)
     235                 :          0 :                 minfo->mod_content[i] = mr_action->mod.data[i];
     236                 :            : 
     237                 :            :         return 0;
     238                 :            : }
     239                 :            : 
     240                 :            : #define CPFL_FXP_MAX_QREGION_SIZE 128
     241                 :            : #define CPFL_INVALID_QUEUE_ID -2
     242                 :            : static int
     243                 :          0 : cpfl_fxp_parse_action(struct cpfl_itf *itf,
     244                 :            :                       const struct rte_flow_action *actions,
     245                 :            :                       const struct cpfl_flow_mr_action *mr_action,
     246                 :            :                       struct cpfl_rule_info_meta *rim,
     247                 :            :                       int priority,
     248                 :            :                       int index)
     249                 :            : {
     250                 :            :         const struct rte_flow_action_ethdev *act_ethdev;
     251                 :            :         const struct rte_flow_action *action;
     252                 :            :         const struct rte_flow_action_queue *act_q;
     253                 :            :         const struct rte_flow_action_rss *rss;
     254                 :            :         struct rte_eth_dev_data *data;
     255                 :            :         enum rte_flow_action_type action_type;
     256                 :            :         struct cpfl_vport *vport;
     257                 :            :         /* used when action is PORT_REPRESENTOR type */
     258                 :            :         struct cpfl_itf *dst_itf;
     259                 :            :         uint16_t dev_id; /* vsi id */
     260                 :            :         int queue_id = -1;
     261                 :            :         bool fwd_vsi = false;
     262                 :            :         bool fwd_q = false;
     263                 :            :         bool is_vsi;
     264                 :            :         uint32_t i;
     265                 :          0 :         struct cpfl_rule_info *rinfo = &rim->rules[index];
     266                 :          0 :         union cpfl_action_set *act_set = (void *)rinfo->act_bytes;
     267                 :            : 
     268                 :          0 :         priority = CPFL_PREC_MAX - priority;
     269         [ #  # ]:          0 :         for (action = actions; action->type !=
     270                 :          0 :              RTE_FLOW_ACTION_TYPE_END; action++) {
     271                 :            :                 action_type = action->type;
     272   [ #  #  #  #  :          0 :                 switch (action_type) {
                   #  # ]
     273                 :          0 :                 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
     274                 :            :                 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
     275         [ #  # ]:          0 :                         if (!fwd_vsi)
     276                 :            :                                 fwd_vsi = true;
     277                 :            :                         else
     278                 :          0 :                                 goto err;
     279                 :            : 
     280                 :          0 :                         act_ethdev = action->conf;
     281                 :          0 :                         dst_itf = cpfl_get_itf_by_port_id(act_ethdev->port_id);
     282                 :            : 
     283         [ #  # ]:          0 :                         if (!dst_itf)
     284                 :          0 :                                 goto err;
     285                 :            : 
     286         [ #  # ]:          0 :                         if (dst_itf->type == CPFL_ITF_TYPE_VPORT) {
     287                 :            :                                 vport = (struct cpfl_vport *)dst_itf;
     288                 :          0 :                                 queue_id = vport->base.chunks_info.rx_start_qid;
     289                 :            :                         } else {
     290                 :            :                                 queue_id = CPFL_INVALID_QUEUE_ID;
     291                 :            :                         }
     292                 :            : 
     293   [ #  #  #  # ]:          0 :                         is_vsi = (action_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR ||
     294                 :            :                                   dst_itf->type == CPFL_ITF_TYPE_REPRESENTOR);
     295         [ #  # ]:          0 :                         if (is_vsi)
     296                 :          0 :                                 dev_id = cpfl_get_vsi_id(dst_itf);
     297                 :            :                         else
     298                 :            :                                 dev_id = cpfl_get_port_id(dst_itf);
     299                 :            : 
     300         [ #  # ]:          0 :                         if (dev_id == CPFL_INVALID_HW_ID)
     301                 :          0 :                                 goto err;
     302                 :            : 
     303         [ #  # ]:          0 :                         if (is_vsi)
     304         [ #  # ]:          0 :                                 *act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);
     305                 :            :                         else
     306         [ #  # ]:          0 :                                 *act_set = cpfl_act_fwd_port(0, priority, 0, dev_id);
     307                 :          0 :                         act_set++;
     308                 :          0 :                         rinfo->act_byte_len += sizeof(union cpfl_action_set);
     309                 :          0 :                         break;
     310                 :          0 :                 case RTE_FLOW_ACTION_TYPE_QUEUE:
     311         [ #  # ]:          0 :                         if (!fwd_q)
     312                 :            :                                 fwd_q = true;
     313                 :            :                         else
     314                 :          0 :                                 goto err;
     315         [ #  # ]:          0 :                         if (queue_id == CPFL_INVALID_QUEUE_ID)
     316                 :          0 :                                 goto err;
     317                 :          0 :                         act_q = action->conf;
     318                 :          0 :                         data = itf->data;
     319         [ #  # ]:          0 :                         if (act_q->index >= data->nb_rx_queues)
     320                 :          0 :                                 goto err;
     321                 :            : 
     322                 :            :                         vport = (struct cpfl_vport *)itf;
     323         [ #  # ]:          0 :                         if (queue_id < 0)
     324                 :          0 :                                 queue_id = vport->base.chunks_info.rx_start_qid;
     325                 :          0 :                         queue_id += act_q->index;
     326         [ #  # ]:          0 :                         *act_set = cpfl_act_set_hash_queue(priority, 0, queue_id, 0);
     327                 :          0 :                         act_set++;
     328                 :          0 :                         rinfo->act_byte_len += sizeof(union cpfl_action_set);
     329                 :          0 :                         break;
     330                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
     331                 :          0 :                         rss = action->conf;
     332         [ #  # ]:          0 :                         if (rss->queue_num <= 1)
     333                 :          0 :                                 goto err;
     334         [ #  # ]:          0 :                         for (i = 0; i < rss->queue_num - 1; i++) {
     335         [ #  # ]:          0 :                                 if (rss->queue[i + 1] != rss->queue[i] + 1)
     336                 :          0 :                                         goto err;
     337                 :            :                         }
     338                 :          0 :                         data = itf->data;
     339         [ #  # ]:          0 :                         if (rss->queue[rss->queue_num - 1] >= data->nb_rx_queues)
     340                 :          0 :                                 goto err;
     341         [ #  # ]:          0 :                         if (!(rte_is_power_of_2(rss->queue_num) &&
     342                 :            :                               rss->queue_num <= CPFL_FXP_MAX_QREGION_SIZE))
     343                 :          0 :                                 goto err;
     344                 :            : 
     345         [ #  # ]:          0 :                         if (!fwd_q)
     346                 :            :                                 fwd_q = true;
     347                 :            :                         else
     348                 :          0 :                                 goto err;
     349         [ #  # ]:          0 :                         if (queue_id == CPFL_INVALID_QUEUE_ID)
     350                 :          0 :                                 goto err;
     351                 :            :                         vport = (struct cpfl_vport *)itf;
     352         [ #  # ]:          0 :                         if (queue_id < 0)
     353                 :          0 :                                 queue_id = vport->base.chunks_info.rx_start_qid;
     354                 :          0 :                         queue_id += rss->queue[0];
     355                 :          0 :                         *act_set = cpfl_act_set_hash_queue_region(priority, 0, queue_id,
     356         [ #  # ]:          0 :                                                                   log(rss->queue_num) / log(2), 0);
     357                 :          0 :                         act_set++;
     358                 :          0 :                         rinfo->act_byte_len += sizeof(union cpfl_action_set);
     359                 :          0 :                         break;
     360                 :          0 :                 case RTE_FLOW_ACTION_TYPE_DROP:
     361         [ #  # ]:          0 :                         (*act_set).data = cpfl_act_drop(priority).data;
     362                 :            :                         act_set++;
     363         [ #  # ]:          0 :                         rinfo->act_byte_len += sizeof(union cpfl_action_set);
     364                 :          0 :                         (*act_set).data = cpfl_act_set_commit_mode(priority, 0).data;
     365                 :          0 :                         act_set++;
     366                 :          0 :                         rinfo->act_byte_len += sizeof(union cpfl_action_set);
     367                 :          0 :                         break;
     368                 :            :                 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
     369                 :            :                 case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
     370                 :            :                 case RTE_FLOW_ACTION_TYPE_PROG:
     371                 :            :                         break;
     372                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
     373                 :            :                         break;
     374                 :          0 :                 default:
     375                 :          0 :                         goto err;
     376                 :            :                 }
     377                 :            :         }
     378                 :            : 
     379         [ #  # ]:          0 :         if (mr_action) {
     380                 :            :                 uint32_t i;
     381                 :            : 
     382         [ #  # ]:          0 :                 for (i = 0; i < rim->mr_num; i++)
     383         [ #  # ]:          0 :                         if (cpfl_parse_mod_content(itf->adapter, rinfo,
     384                 :          0 :                                                    &rim->rules[rim->pr_num + i],
     385                 :          0 :                                                    &mr_action[i]))
     386                 :          0 :                                 goto err;
     387                 :            :         }
     388                 :            : 
     389                 :            :         return 0;
     390                 :            : 
     391                 :          0 : err:
     392                 :          0 :         PMD_DRV_LOG(ERR, "Invalid action type");
     393                 :          0 :         return -EINVAL;
     394                 :            : }
     395                 :            : 
     396                 :            : static void
     397                 :            : cpfl_fill_rinfo_default_value(struct cpfl_rule_info *rinfo)
     398                 :            : {
     399         [ #  # ]:          0 :         if (cpfl_rule_cookie == ~0llu)
     400                 :          0 :                 cpfl_rule_cookie = CPFL_COOKIE_DEF;
     401                 :          0 :         rinfo->cookie = cpfl_rule_cookie++;
     402                 :          0 :         rinfo->host_id = CPFL_HOST_ID_DEF;
     403                 :          0 :         rinfo->port_num = CPFL_PORT_NUM_DEF;
     404                 :          0 :         rinfo->resp_req = CPFL_RESP_REQ_DEF;
     405                 :          0 :         rinfo->clear_mirror_1st_state = CPFL_CLEAR_MIRROR_1ST_STATE_DEF;
     406                 :            : }
     407                 :            : 
     408                 :            : static bool
     409                 :            : cpfl_is_mod_action(const struct rte_flow_action actions[])
     410                 :            : {
     411                 :            :         const struct rte_flow_action *action;
     412                 :            :         enum rte_flow_action_type action_type;
     413                 :            : 
     414   [ #  #  #  # ]:          0 :         if (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END)
     415                 :            :                 return false;
     416                 :            : 
     417         [ #  # ]:          0 :         for (action = actions; action->type !=
     418                 :          0 :                         RTE_FLOW_ACTION_TYPE_END; action++) {
     419                 :            :                 action_type = action->type;
     420         [ #  # ]:          0 :                 switch (action_type) {
     421                 :            :                 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
     422                 :            :                 case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
     423                 :            :                 case RTE_FLOW_ACTION_TYPE_PROG:
     424                 :            :                         return true;
     425                 :          0 :                 default:
     426                 :            :                         continue;
     427                 :            :                 }
     428                 :            :         }
     429                 :            :         return false;
     430                 :            : }
     431                 :            : 
     432                 :            : static bool
     433                 :          0 : cpfl_fxp_get_metadata_port(struct cpfl_itf *itf,
     434                 :            :                            const struct rte_flow_action actions[])
     435                 :            : {
     436                 :            :         const struct rte_flow_action *action;
     437                 :            :         enum rte_flow_action_type action_type;
     438                 :            :         const struct rte_flow_action_ethdev *ethdev;
     439                 :            :         struct cpfl_itf *target_itf;
     440                 :            :         bool ret;
     441                 :            : 
     442         [ #  # ]:          0 :         if (itf->type == CPFL_ITF_TYPE_VPORT) {
     443                 :          0 :                 ret = cpfl_metadata_write_port_id(itf);
     444         [ #  # ]:          0 :                 if (!ret) {
     445                 :          0 :                         PMD_DRV_LOG(ERR, "fail to write port id");
     446                 :          0 :                         return false;
     447                 :            :                 }
     448                 :            :         }
     449                 :            : 
     450                 :          0 :         ret = cpfl_metadata_write_sourcevsi(itf);
     451         [ #  # ]:          0 :         if (!ret) {
     452                 :          0 :                 PMD_DRV_LOG(ERR, "fail to write source vsi id");
     453                 :          0 :                 return false;
     454                 :            :         }
     455                 :            : 
     456                 :          0 :         ret = cpfl_metadata_write_vsi(itf);
     457         [ #  # ]:          0 :         if (!ret) {
     458                 :          0 :                 PMD_DRV_LOG(ERR, "fail to write vsi id");
     459                 :          0 :                 return false;
     460                 :            :         }
     461                 :            : 
     462   [ #  #  #  # ]:          0 :         if (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END)
     463                 :            :                 return false;
     464                 :            : 
     465         [ #  # ]:          0 :         for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
     466                 :            :                 action_type = action->type;
     467         [ #  # ]:          0 :                 switch (action_type) {
     468                 :          0 :                 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
     469                 :            :                 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
     470                 :          0 :                         ethdev = (const struct rte_flow_action_ethdev *)action->conf;
     471                 :          0 :                         target_itf = cpfl_get_itf_by_port_id(ethdev->port_id);
     472         [ #  # ]:          0 :                         if (!target_itf) {
     473                 :          0 :                                 PMD_DRV_LOG(ERR, "fail to get target_itf by port id");
     474                 :          0 :                                 return false;
     475                 :            :                         }
     476                 :          0 :                         ret = cpfl_metadata_write_targetvsi(target_itf);
     477         [ #  # ]:          0 :                         if (!ret) {
     478                 :          0 :                                 PMD_DRV_LOG(ERR, "fail to write target vsi id");
     479                 :          0 :                                 return false;
     480                 :            :                         }
     481                 :            :                         break;
     482                 :          0 :                 default:
     483                 :          0 :                         continue;
     484                 :            :                 }
     485                 :            :         }
     486                 :            : 
     487                 :            :         return true;
     488                 :            : }
     489                 :            : 
     490                 :            : static int
     491                 :          0 : cpfl_fxp_parse_pattern_action(struct rte_eth_dev *dev,
     492                 :            :                               const struct rte_flow_attr *attr,
     493                 :            :                               const struct rte_flow_item pattern[],
     494                 :            :                               const struct rte_flow_action actions[],
     495                 :            :                               void **meta)
     496                 :            : {
     497                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
     498                 :          0 :         struct cpfl_flow_pr_action pr_action = { 0 };
     499                 :          0 :         struct cpfl_adapter_ext *adapter = itf->adapter;
     500                 :          0 :         struct cpfl_flow_mr_action mr_action[CPFL_MAX_MR_ACTION_NUM] = { 0 };
     501                 :            :         uint32_t pr_num = 0;
     502                 :            :         uint32_t mr_num = 0;
     503                 :            :         struct cpfl_rule_info_meta *rim;
     504                 :            :         int ret;
     505                 :            : 
     506                 :          0 :         ret = cpfl_fxp_get_metadata_port(itf, actions);
     507         [ #  # ]:          0 :         if (!ret) {
     508                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to save metadata.");
     509                 :          0 :                 return -EINVAL;
     510                 :            :         }
     511                 :            : 
     512                 :          0 :         ret = cpfl_flow_parse_items(itf, adapter->flow_parser, pattern, attr, &pr_action);
     513         [ #  # ]:          0 :         if (ret) {
     514                 :          0 :                 PMD_DRV_LOG(ERR, "No Match pattern support.");
     515                 :          0 :                 return -EINVAL;
     516                 :            :         }
     517                 :            : 
     518         [ #  # ]:          0 :         if (cpfl_is_mod_action(actions)) {
     519                 :          0 :                 ret = cpfl_flow_parse_actions(adapter->flow_parser, actions, mr_action);
     520         [ #  # ]:          0 :                 if (ret) {
     521                 :          0 :                         PMD_DRV_LOG(ERR, "action parse fails.");
     522                 :          0 :                         return -EINVAL;
     523                 :            :                 }
     524                 :            :                 mr_num++;
     525                 :            :         }
     526                 :            : 
     527                 :            :         pr_num = 1;
     528                 :          0 :         rim = rte_zmalloc(NULL,
     529                 :            :                           sizeof(struct cpfl_rule_info_meta) +
     530                 :          0 :                           (pr_num + mr_num) * sizeof(struct cpfl_rule_info),
     531                 :            :                           0);
     532         [ #  # ]:          0 :         if (!rim)
     533                 :            :                 return -ENOMEM;
     534                 :            : 
     535                 :          0 :         rim->pr_action = pr_action;
     536                 :          0 :         rim->pr_num = pr_num;
     537                 :          0 :         rim->mr_num = mr_num;
     538                 :          0 :         rim->rule_num = pr_num + mr_num;
     539                 :            : 
     540         [ #  # ]:          0 :         if (!cpfl_fxp_parse_pattern(&pr_action, rim, 0)) {
     541                 :          0 :                 PMD_DRV_LOG(ERR, "Invalid pattern");
     542                 :          0 :                 rte_free(rim);
     543                 :          0 :                 return -rte_errno;
     544                 :            :         }
     545                 :            : 
     546         [ #  # ]:          0 :         if (cpfl_fxp_parse_action(itf, actions, mr_action, rim, attr->priority, 0)) {
     547                 :          0 :                 PMD_DRV_LOG(ERR, "Invalid action");
     548                 :          0 :                 rte_free(rim);
     549                 :          0 :                 return -rte_errno;
     550                 :            :         }
     551                 :            : 
     552                 :            :         cpfl_fill_rinfo_default_value(&rim->rules[0]);
     553                 :            : 
     554         [ #  # ]:          0 :         if (!meta)
     555                 :          0 :                 rte_free(rim);
     556                 :            :         else
     557                 :          0 :                 *meta = rim;
     558                 :            : 
     559                 :            :         return 0;
     560                 :            : }
     561                 :            : 
     562                 :            : static int
     563                 :          0 : cpfl_fxp_mod_init(struct cpfl_adapter_ext *ad)
     564                 :            : {
     565                 :            :         uint32_t size = rte_bitmap_get_memory_footprint(CPFL_MAX_MOD_CONTENT_INDEX);
     566                 :          0 :         void *mem = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
     567                 :            : 
     568         [ #  # ]:          0 :         if (!mem)
     569                 :            :                 return -ENOMEM;
     570                 :            : 
     571                 :            :         /* a set bit represent a free slot */
     572                 :          0 :         ad->mod_bm = rte_bitmap_init_with_all_set(CPFL_MAX_MOD_CONTENT_INDEX, mem, size);
     573         [ #  # ]:          0 :         if (!ad->mod_bm) {
     574                 :          0 :                 rte_free(mem);
     575                 :          0 :                 return -EINVAL;
     576                 :            :         }
     577                 :            : 
     578                 :          0 :         ad->mod_bm_mem = mem;
     579                 :            : 
     580                 :          0 :         return 0;
     581                 :            : }
     582                 :            : 
     583                 :            : static void
     584                 :            : cpfl_fxp_mod_uninit(struct cpfl_adapter_ext *ad)
     585                 :            : {
     586                 :          0 :         rte_free(ad->mod_bm_mem);
     587                 :          0 :         ad->mod_bm_mem = NULL;
     588                 :          0 :         ad->mod_bm = NULL;
     589                 :            : }
     590                 :            : 
     591                 :            : static uint32_t
     592                 :          0 : cpfl_fxp_mod_idx_alloc(struct cpfl_adapter_ext *ad)
     593                 :            : {
     594                 :          0 :         uint64_t slab = 0;
     595                 :          0 :         uint32_t pos = 0;
     596                 :            : 
     597         [ #  # ]:          0 :         if (!rte_bitmap_scan(ad->mod_bm, &pos, &slab))
     598                 :            :                 return CPFL_MAX_MOD_CONTENT_INDEX;
     599                 :            : 
     600                 :          0 :         pos += __builtin_ffsll(slab) - 1;
     601                 :          0 :         rte_bitmap_clear(ad->mod_bm, pos);
     602                 :            : 
     603                 :          0 :         return pos;
     604                 :            : }
     605                 :            : 
     606                 :            : static void
     607                 :            : cpfl_fxp_mod_idx_free(struct cpfl_adapter_ext *ad, uint32_t idx)
     608                 :            : {
     609                 :          0 :         rte_bitmap_set(ad->mod_bm, idx);
     610                 :            : }
     611                 :            : 
     612                 :            : static int
     613                 :          0 : cpfl_fxp_query(struct rte_eth_dev *dev __rte_unused,
     614                 :            :                struct rte_flow *flow __rte_unused,
     615                 :            :                struct rte_flow_query_count *count __rte_unused,
     616                 :            :                struct rte_flow_error *error)
     617                 :            : {
     618                 :          0 :         rte_flow_error_set(error, EINVAL,
     619                 :            :                            RTE_FLOW_ERROR_TYPE_HANDLE,
     620                 :            :                            NULL,
     621                 :            :                            "count action not supported by this module");
     622                 :            : 
     623                 :          0 :         return -rte_errno;
     624                 :            : }
     625                 :            : 
     626                 :            : static void
     627                 :          0 : cpfl_fxp_uninit(struct cpfl_adapter_ext *ad)
     628                 :            : {
     629                 :            :         cpfl_fxp_mod_uninit(ad);
     630                 :          0 : }
     631                 :            : 
     632                 :            : static int
     633                 :          0 : cpfl_fxp_init(struct cpfl_adapter_ext *ad)
     634                 :            : {
     635                 :            :         int ret = 0;
     636                 :            : 
     637                 :          0 :         ret = cpfl_fxp_mod_init(ad);
     638         [ #  # ]:          0 :         if (ret) {
     639                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init mod content bitmap.");
     640                 :          0 :                 return ret;
     641                 :            :         }
     642                 :            : 
     643                 :            :         return ret;
     644                 :            : }
     645                 :            : 
     646                 :            : static struct
     647                 :            : cpfl_flow_engine cpfl_fxp_engine = {
     648                 :            :         .type = CPFL_FLOW_ENGINE_FXP,
     649                 :            :         .init = cpfl_fxp_init,
     650                 :            :         .uninit = cpfl_fxp_uninit,
     651                 :            :         .create = cpfl_fxp_create,
     652                 :            :         .destroy = cpfl_fxp_destroy,
     653                 :            :         .query_count = cpfl_fxp_query,
     654                 :            :         .parse_pattern_action = cpfl_fxp_parse_pattern_action,
     655                 :            : };
     656                 :            : 
     657                 :        235 : RTE_INIT(cpfl_sw_engine_init)
     658                 :            : {
     659                 :            :         struct cpfl_flow_engine *engine = &cpfl_fxp_engine;
     660                 :            : 
     661                 :        235 :         cpfl_flow_engine_register(engine);
     662                 :        235 : }

Generated by: LCOV version 1.14